ColdFusion help in Dreamweaver MX is a subset of the documentation in ColdFusion MX. It includes all the topics that ColdFusion developers might find useful, including a full language reference. It does not include topics unrelated to creating dynamic sites, such as advanced server administration.

The ColdFusion help system in Dreamweaver contains the following parts:

  • Installing ColdFusion MX is intended for anyone who needs to install and configure ColdFusion MX
  • Getting Started with Building ColdFusion Applications is intended for anyone who wants to learn how to use ColdFusion to create web applications
  • Migrating from ColdFusion 5 is intended for anyone who needs to migrate from ColdFusion 5 Server to ColdFusion MX
  • CFML Reference is your primary ColdFusion Markup Language (CFML) reference guide. Use this guide to learn about individual CFML tags and functions, as well as ColdFusion expressions, using JavaScript objects for WDDX in ColdFusion
  • Developing ColdFusion Applications provides the tools you need to develop web applications using ColdFusion. This part is intended for web application programmers learning ColdFusion or who wish to extend their ColdFusion programming knowledge
  • Using Server-side ActionScript is intended for anyone who wants to learn to access ColdFusion services using ActionScript, the scripting language associated with Macromedia Flash

The complete set of ColdFusion documentation is available in PDF format on the Dreamweaver MX CD.

You can download and install a fully functional, developer edition of ColdFusion MX from the Macromedia website. The Windows version of the Dreamweaver MX CD includes a copy of ColdFusion MX Server Developer Edition.

To install ColdFusion MX:

  1. Make sure you install ColdFusion MX on a supported system.

    2. For more information, see “System Requirements” in ColdFusion help.

  2. Close all open applications.
  3. Double-click the ColdFusion MX installer file.
  4. Follow the installation instructions.

    5. For more information, see “Installing ColdFusion” in ColdFusion help.


About This Book

Installing ColdFusion MX is intended for anyone who needs to install and configure ColdFusion MX.

Contents
  • Developer resources
  • About Macromedia ColdFusion MX documentation
  • Getting answers
  • Contacting Macromedia
Next


Developer resources

Macromedia, Inc. is committed to setting the standard for customer support in developer education, technical support, and professional services. The Macromedia website is designed to give you quick access to the entire range of online resources. The following table shows the locations of these resources.

Resource | Description | URL
Macromedia website | General information about Macromedia products and services | www.macromedia.com
Information on ColdFusion | Detailed product information on ColdFusion and related topics | www.macromedia.com/coldfusion
Macromedia ColdFusion Support Center | Professional support programs that Macromedia offers. | www.macromedia.com/support/coldfusion
ColdFusion Online Forum | Access to experienced ColdFusion developers through participation in the Online Forums, where you can post messages and read replies on many subjects relating to ColdFusion. | http://webforums.macromedia.com/coldfusion/
Installation Support | Support for installation-related issues for all Macromedia products | www.macromedia.com/support/coldfusion/installation.html
Training | Information about classes, on-site training, and online courses offered by Macromedia | www.macromedia.com/support/training
Developer Resources | All the resources that you need to stay on the cutting edge of ColdFusion development, including online discussion groups, Knowledge Base, technical papers, and more | www.macromedia.com/desdev/developer/
Reference Desk | Development tips, articles, documentation, and white papers | www.macromedia.com/v1/developer/TechnologyReference/index.cfm
Macromedia Alliance | Connection with the growing network of solution providers, application developers, resellers, and hosting services creating solutions with ColdFusion | www.coldfusion.com/partners/


About Macromedia ColdFusion MX documentation

The ColdFusion documentation is designed to provide support for the complete spectrum of participants. The print and online versions are organized to let you quickly locate the information that you need. The ColdFusion online documentation is provided in HTML and Adobe Acrobat formats.


Printed and online documentation set

The ColdFusion documentation set consists of the following titles:

Book | Description
Installing ColdFusion MX | Describes system installation and basic configuration for Windows NT, Windows 2000, Solaris, Linux, and HP-UX.
Administering ColdFusion MX | Describes how to use the ColdFusion Administrator to manage the ColdFusion environment, including connecting to your data sources and configuring security for your applications,
Developing ColdFusion MX Applications with CFML | Describes how to develop your dynamic web applications, including retrieving and updating your data, using structures, and forms.
Getting Started Building ColdFusion MX Applications | Contains an overview of ColdFusion features and application development procedures. Includes a tutorial that guides you through the process of developing an example ColdFusion application.
Using Server-Side ActionScript in ColdFusion MX | Describes how Macromedia Flash movies executing on a client browser can call ActionScript code running on the ColdFusion server. Includes examples of server-side ActionScript and a syntax guide for developing ActionScript pages on the server.
Migrating ColdFusion 5 Applications | Describes how to migrate a ColdFusion 5 application to ColdFusion MX. This book describes the code compatibility analyzer that evaluates your ColdFusion 5 code to determine any incompatibilities within it.
CFML Reference | Provides descriptions, syntax, usage, and code examples for all ColdFusion tags, functions, and variables.
CFML Quick Reference | A brief guide that shows the syntax of ColdFusion tags, functions, and variables.
Working with Verity Tools | Describes Verity search tools and utilities that you can use for configuring the Verity K2 Server search engine, as well as creating, managing, and troubleshooting Verity collections.
Using ClusterCATS | Describes how to use Macromedia ClusterCATS, the clustering technology that provides load-balancing and failover services to assure high availability for your web servers.


Viewing online documentation

All ColdFusion documentation is available online in HTML and Adobe Acrobat Portable Document Format (PDF) files. To view the HTML documentation, open the following URL on the web server running ColdFusion: http://web_root/cfdocs/dochome.htm.

ColdFusion documentation in Acrobat format is available on the ColdFusion product CD-ROM.


Getting answers

One of the best ways to solve particular programming problems is to tap into the vast expertise of the ColdFusion developer communities on the ColdFusion Forums. Other developers on the forum can help you figure out how to do just about anything with ColdFusion. The search facility can also help you search messages from the previous 12 months, allowing you to learn how others have solved a problem that you might be facing. The Forums is a great resource for learning ColdFusion, but it is also a great place to see the ColdFusion developer community in action.


Contacting Macromedia

Corporate headquarters
Macromedia, Inc.
600 Townsend Street
San Francisco, CA 94103
Tel: 415.252.2000
Fax: 415.626.0554
Web: http:// www.macromedia.com
Technical support
Macromedia offers a range of telephone and web-based support options. Go to http://www.macromedia.com/support/coldfusionfor a complete description of technical support services.
You can make postings to the ColdFusion Support Forum (http://webforums.macromedia.com/coldfusion) at any time.
Sales
Toll Free: 888.939.2545
Tel: 617.219.2100
Fax: 617.219.2101
E-mail: sales@macromedia.com
Web: http://commerce.coldfusion.com/purchase/index.cfm

Previous


Installing Macromedia ColdFusion MX

This chapter describes Macromedia ColdFusion MX system requirements, how to begin the installation, and how to uninstall ColdFusion MX.

Note: In this chapter, cf_root refers to your installation directory. By default, this directory is c:\CFusionMX in Windows, and /opt/coldfusionmx in UNIX.

Contents
  • ColdFusion MX product editions
  • System requirements
  • Installation considerations
  • Installing ColdFusion MX
  • Installing Verity Locales
  • ColdFusion MX directory structure
  • Using the ColdFusion MX web server
  • Uninstalling ColdFusion MX
Next


ColdFusion MX product editions

The following table describes each edition of ColdFusion MX:

Edition
Description
Licensing
Developer
For Windows, Linux, Solaris, and HP-UX platforms.
Includes every feature in the Enterprise edition except Macromedia ClusterCATS. After 30 days, it expires to only support requests from one IP address.
Free for noncommercial use, for developing and testing web applications on a local host and one remote IP address. Not licensed for deployment.
Professional
For Windows and Linux platforms.
Features full ColdFusion Markup Language (CFML) support, including:
  • Custom tags and ColdFusion components
  • Full support for server-side ActionScript and Flash Remoting
  • Database connectivity using ODBC with a desktop database, and using a Type 4 driver for SQL Server or MySQL (if available)
  • Extensibility and integration with Simple Object Access Protocol (SOAP) and Extensible Markup Language (XML), and with Component Object Model (COM), Enterprise Java Beans (EJBs), and Common Object Request Broker Architecture (CORBA)
  • Database and LDAP directory authentication, and security on tags
  • A graphing engine
  • A 125K document search
Licensed per server (up to 2 processors per server).
Enterprise
For Windows, Linux, Solaris, and HP-UX platforms.
Includes every feature in the Professional edition, and also provides database connectivity using a Type 4 driver for Oracle, DB2, Sybase, and Informix; the ability to code JTL imports and JSP includes; server sandbox security; a 250k document search; advanced server management capabilities (probes and alarms, archive and deploy); and HTTP-based load-balancing and fail-over using Macromedia ClusterCATS (installed separately).
Licensed per server (up to 8 processors per server).


System requirements

This section lists the system requirements for ColdFusion MX on Windows and UNIX.

Note: If you use Macromedia ColdFusion Studio to develop your web applications, note that ColdFusion MX only supports ColdFusion Studio versions 4.5.2 and 5.0.


System requirements for Windows

This section lists the Windows system requirements for the Macromedia ColdFusion MX Server Developer, Professional, and Enterprise Editions. An “x” in the following table means that the Edition supports the requirement in that row.

Requirement | Developer Edition | Professional Edition | Enterprise Edition
Windows version
Windows 98* | x | x | x
Windows Millennium Edition (ME)* | x | x |
Windows NT 4.0 (Workstation and Server) SP6A | x | x | x
Windows NT 4 Server, Enterprise Edition | x | x | x
Windows 2000 (Professional SP2, Server SP2, Advanced Server, and Datacenter Server) | x | x | x
Windows XP (Home and Professional) | x | x | x
Hardware
Processor | Pentium | Pentium | Pentium
Minimum RAM (MB) | 128 | 256 | 256
Recommended RAM (MB) | 256 | 512 | 512
Free hard disk space (MB) | 400 to install 250 to run | 400 to install 250 to run | 400 to install 250 to run
CD-ROM drive | x | x | x
Web servers
ColdFusion MX standalone web server | x | x | x
Microsoft IIS 4.0, 5.x | x | x | x
Netscape Enterprise Server 3.6x | x | x | x
iPlanet Enterprise Server 4.x, 6.x | x | x | x
Apache web server 1.3.12–1.3.22, 2.x | x | x | x
Java Virtual Machine (JVM)
Sun JDK/JRE 1.3.1 or later | x | x | x
IBM JVM 1.2.2–1.3 or later | x | x | x
Browsers
Internet Explorer 5.x, 6 | x | x | x
Netscape Communicator 4, 6 | x | x | x
Databases
Oracle 8.1.7, 9i | x | x | x
Sybase 11.9.2, 12 | x | x | x
DB2 6.2, 7.2 | x | x | x
Informix 9.x | x | x | x
Microsoft SQLServer 7.x, 2000 | x | x | x
Microsoft Access | x | x | x
SQLAnywhere£ | x | x | x
MySQL£ | x | x | x
PostGreSQL£ | x | x | x

* ColdFusion MX only supports the standalone web server for this platform. Note that Macromedia does not recommend using the standalone web server in a production environment.

To install ColdFusion MX on Windows NT 4.0 Server or Windows 2000 Server, you must already have the following components installed: MDAC 2.5 SP1
(http://www.microsoft.com/data/download.htm) and MFC/MSVC 6.0
(localdrive\ColdFusion Image\Redistrib\MSVCRT\setup.exe).

The Macromedia ColdFusion MX team has tested integration with the .Net Framework version 1 and Service Pack 1.

£ ColdFusion MX does not include the driver for this database. For more information, see Connecting to an external JDBC Type 4 data source.


System requirements for UNIX

This section lists the UNIX system requirements for the Macromedia ColdFusion MX Server Developer, Professional, and Enterprise Editions. An “x” in the following table means that the edition supports the requirement in that row.

Requirement | Developer Edition | Professional Edition | Enterprise Edition
UNIX distributions
Red Hat Linux 6.2–7.2 Install the latest patches (including the kernel) from ftp://ftp.redhat.com/pub | x | x | x
SuSE Linux 7.2, 7.3 Install the latest patches (including the kernel) from ftp://ftp.suse.com/pub | x | x | x
Solaris 7, 8 For Solaris 7, install the latest patch bundles from http://sunsolve.sun.com/pub-cgi/show.pl?target=patches/patch-access |  |  | x
HP-UX 11.00 Install the latest patch bundles from the Hewlett-Packard website at http://www.hp.com |  |  | x
Hardware
Processor | Pentium for Linux, SPARC for Solaris, and PA-RISC version 1.1 or 2.0 for HP-UX
Minimum RAM (MB) | 256 | 256 | 256
Recommended RAM (MB) | 512 | 512 | 512
Free hard disk space (MB) | 350 to install 250 to run | 350 to install 250 to run | 350 to install 250 to run
CD-ROM drive | x | x | x
Web servers
ColdFusion MX internal port-based web server | x | x | x
Apache web server 1.3.12–1.3.22, 2.x | x | x | x
Netscape Enterprise Server 3.6x | x | x | x
iPlanet Enterprise Server 4.x, 6.x | x | x | x
Java Virtual Machine (JVM)
Sun JDK/JRE 1.3.1 or later | x | x | x
IBM JVM 1.3 or later | x | x | x
Browsers
Internet Explorer 5.x, 6 | x | x | x
Netscape Communicator 4, 6 | x | x | x
Databases
Oracle 8.1.7, 9i | x | x | x
Sybase 11.9.2, 12 | x | x | x
DB2 6.2, 7.2 | x | x | x
Informix 9.x | x | x | x
SQLServer 7.x, 2000 | x | x | x
Microsoft Access | x | x | x
SQLAnywhere* | x | x | x
MySQL* | x | x | x
PostGreSQL* | x | x | x

* ColdFusion MX does not include the driver for this database. For more information, see Connecting to an external JDBC Type 4 data source.


Installation considerations

This section lists considerations for installing or upgrading to ColdFusion MX.

Note: To use VisiBroker for CORBA connections in ColdFusion MX, see Enabling CORBA support. To install ClusterCATS, see Using ClusterCATS.


Installation considerations for all platforms

The following are installation considerations for all platforms:

  • Macromedia only supports upgrading to ColdFusion MX from ColdFusion 5. If you are upgrading, you must back up your ColdFusion MX web applications first.
  • If you have previously installed a beta version of ColdFusion MX, you must uninstall it before you install the release version.
  • Macromedia recommends using the standalone (internal port-based) web server for development, but not in a production environment.
  • To interact with ColdFusion pages, components, and server-side ActionScript from a Flash movie, use the Flash Remoting service in ColdFusion MX. While no special installations are required to develop ColdFusion applications for the Flash Remoting service, you must install the Flash Remoting Components in the Flash MX authoring environment. The Flash MX authoring environment is required to build applications that connect to and interact with the Flash Remoting service in ColdFusion.

    • For more information on Flash Remoting, see Developing ColdFusion MX Applications with CFML.

  • ColdFusion MX is built in Java. For ColdFusion MX (or any Java application) to run on your computer, you must have the Java Runtime Environment (JRE) installed. The installer installs the JRE that is optimal for ColdFusion MX on your platform.
  • In an optimal production environment, each ColdFusion MX application is hosted on a dedicated server; database, mail, and other servers are not on the same computer.


Installation considerations for Windows

The following are installation considerations for Windows only:

  • Do not configure the server running ColdFusion MX as a Primary Domain Controller (PDC) or Backup Domain Controller (BDC). Macromedia follows Microsoft’s network model, in which the first level is the PDC/BDC. These systems only manage the network or domain and are not designed to run application servers. ColdFusion MX should reside on the second level of Windows NT and Windows 2000 standalone systems. Standalone servers can participate in a network or domain.
  • Windows NT 4.0 Workstation and Windows 2000 Professional handle only 10 TCP/IP connections concurrently. Therefore, Macromedia does not recommend using these operating systems in a production environment; use Window NT 4.0 Server or Windows 2000 Server instead. In addition, Macromedia does not recommend using Windows ME, Windows 98, or Windows XP Home Edition, because each was intended for personal use and not as a server platform in a production environment.
  • During installation, if you select the standalone web server, your web root directory will be c:\cfusionmx\wwwroot by default. This web server runs on the 8500 port. To display a page, append 8500 to the end of the host name or IP address; for example, http://localhost:8500/MyApp.cfm. (If the page still does not display, make sure that the document is located in the ColdFusion MX web root directory; for example, c:\cfusionmx\wwwroot\MyApp.cfm.) For more information, see Using the ColdFusion MX web server.
  • To configure a virtual mapping, edit the jrun-web.xml file in the cf_root\wwwroot\WEB-INF directory. (A virtual mapping lets you map a resource path to a physical system path that might be outside the ColdFusion MX web root.) For example, the following entry sets a virtual path to the /usr/local/images directory on an external UNIX computer:
    • <virtual-mapping>
  <resource-path>/images/*</resource-path>
  <system-path>/usr/local/images</system-path>
</virtual-mapping>


Installation consideration for UNIX

For troubleshooting purposes, the installer creates the following log file during an installation or upgrade on UNIX: cf_root/Macromedia_ColdFusion_MX_install.log. If you contact Macromedia Technical Support for installation support, you must send them this file.


Installing ColdFusion MX

This section provides installation instructions for Windows and UNIX.


Installing ColdFusion MX on Windows

This section explains how to install ColdFusion MX on a Windows platform.

To install ColdFusion MX on Windows:

  1. Read the online version of the Release Notes for any late-breaking information or updates. For more information, see http://www.macromedia.com/go/proddoc_releasenotes.
  2. Make sure that your operating system meets the system requirements described in System requirements for Windows.
  3. Review the Installation considerations.
  4. Close any applications that are currently running on your computer.
  5. Insert the CD-ROM, or download the setup file for your locale from the Macromedia website.
  6. If you are installing from a network or a downloaded file, locate the coldfusionmx executable file for your locale (for example, coldfusionmx-win-us.exe file), and double-click it.

    7. The installation wizard starts.

  7. Follow the instructions in the wizard, and let it run to completion.

    8. After the Pre-Installation Summary pane, the files are copied to your computer. After the installation is complete, the ColdFusion Administrator opens.

  8. If you have an existing ColdFusion 5 installation, you are prompted to migrate your ColdFusion 5 settings to ColdFusion MX.

    9. If you do not want to migrate now, click Skip.

    To migrate later:

    1. Close the ColdFusion Administrator, if it is not already closed.
    2. Change the value of the following registry key from 0 to 1:

      3. HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\Install Data\ColdFusionMX\migrate

    3. Restart the ColdFusion Administrator from the Windows Start menu.

      4. You are prompted again to migrate your ColdFusion 5 settings.

Caution:If you migrate your ColdFusion 5 settings later, you might overwrite new ColdFusion MX settings.

  1. To configure Verity to search in a language other than English, follow the instructions in Installing Verity Locales.
  2. Configure and manage your system, as described in Configuring your System.
  3. To learn about ColdFusion MX, read the documentation that is installed with ColdFusion MX, or download it from the ColdFusion MX documentation website.


Installing ColdFusion on UNIX

This section explains how to install ColdFusion MX on UNIX.

By default, ColdFusion MX installs into the /opt/coldfusionmx directory. To install it into a different directory, you must create that directory before running the installation.

To install ColdFusion MX on UNIX:

  1. Read the online version of the Release Notes for any late-breaking information or updates. For more information, see http://www.macromedia.com/go/proddoc_releasenotes.
  2. Make sure that your operating system meets the system requirements described in System requirements for UNIX.
  3. Review the Installation considerations.
  4. Log in as root.
  5. (HP-UX only) Follow the instructions in Mounting the CD-ROM drive on HP-UX.
  6. Copy the install file that is appropriate for your platform and locale from the CD-ROM or Macromedia website, and save it to a directory on your local disk.

    7. The install files for supported platforms in the English (US) locale are as follows:

  7. cfusionmx_linux_us.bin
  8. cfusionmx_solaris_us.bin
  9. cfusionmx_hp_us.bin
  10. Using the cd command, go to the directory with the install file.
  11. Modify the install file with the following command:
    12. chmod 755 <filename>
  12. Start the installation with the following command:
    13.     ./<filename>

The installation program starts.
  13. Follow the prompts, and let the installation program run to completion.

Caution:For security reasons, it is crucial that you do not use root for the runtime user.

  1. After the install file finishes, start ColdFusion MX with the following command:
    2. /cf_root/bin/coldfusion start

To stop ColdFusion MX, use the following command:

/cf_root/bin/coldfusion stop

For more information on managing processes, see Managing the ColdFusion MX process in UNIX.
  2. (Optional) Open the ColdFusion Administrator in a browser, using the following URL: http://localhost:8500/CFIDE/administrator/index.cfm.

    3. Note: If you are accessing ColdFusion MX from a remote computer, use the previous URL with the host name or IP address of the remote computer instead of localhost.

    If you have an existing ColdFusion 5 installation, when you open the ColdFusion Administrator for the first time, you are prompted to migrate your ColdFusion 5 settings to ColdFusion MX.

    If you do not want to migrate now, click Skip.

    To migrate later:

    1. Close the ColdFusion Administrator, if it is not already closed.
    2. Create a file called upgrade (it can be blank) in your cf_root/bin directory.

      3. The user account under which ColdFusion MX runs must have read/write access to this file. (If you need to change the permissions for the file, use the chmod command.) The file will be deleted once the migration completes.

    3. Start the ColdFusion Administrator.

      4. You are asked again if you want to perform the migration.

Caution:If you migrate your ColdFusion 5 settings later, you might overwrite new ColdFusion MX settings.

  1. To configure Verity to search in a language other than English, follow the instructions in Installing Verity Locales.
  2. Configure and manage your system, as described in Configuring your System.
  3. To learn about ColdFusion MX, read the documentation that is installed with ColdFusion MX, or download it from the ColdFusion MX documentation website.


Mounting the CD-ROM drive on HP-UX

To accommodate long filenames, Macromedia writes ColdFusion MX to the CD-ROM using the RockRidge format. This format is supported by HP-UX using the Portable File System (PFS) commands, not the standard HP-UX mount/umount commands. For more information on PFS commands, enter the following command: man pfs_mount.

To mount the CD-ROM drive on HP-UX using the HP PFS extensions:

  1. Create a mount point for the CD-ROM drive; for example:
    2.    mkdir    /SD_CDROM
  2. Create an entry in the PFS mount file, as follows:
    1. Create or edit the file /etc/pfs_fstab, adding an entry like the following:
      2.     /dev/dsk/c1t2d0  /SD_CDROM      pfs-rrip    xlat=unix  0

(In this example, /dev/dsk/c1t2d0 is the <device_file>, /SD_CDROM is the <mount_point>, pfs-rrip is the <fs_type>, and xlat=unix  0 is the <translation_method>.)
    2. In your entry, ensure that the path that you set in the device_file field is the device name of your CD-ROM drive, and that your mount_point is the name that you selected for the mount point in step 1.
  3. Start the PFS processes, as follows:
    4. nohup /usr/sbin/pfs_mountd &
nohup /usr/sbin/pfsd &
  4. Mount the CD-ROM drive, as follows:
    5. /usr/sbin/pfs_mount /SD_CDROM

The CD-ROM appears under /SD_CDROM.
  5. When you finish using the CD-ROM, you can unmount it using the following command:
    6. /usr/sbin/pfs_umount /SD_CDROM


Installing Verity Locales

ColdFusion MX lets you do Verity searches for languages other than English. For European languages, ColdFusion uses LinguistX technology from Inxight, and for Asian languages, ColdFusion uses ICU (IBM® Classes for Unicode) technology. For more information, see Working with Verity Tools.

This section describes how to install a Verity Locales package from the Macromedia web site, and how to switch to a different Verity Locales package.

To install Verity Locales:

  1. In your browser, go to the following location on the Macromedia web site:

    2. http://www.macromedia.com/go/verity

  2. Enter your ColdFusion MX license key.
  3. Download the appropriate Verity Locales package (.zip file for Windows, .tar file for UNIX), and save it to your cf_root directory.

    4. Select from the following Verity Locales packages: Asian&European and English.

  4. Extract the .zip or .tar file in your cf_root directory.

    5. During extraction, the search files are automatically placed in the appropriate directories under the cf_root\lib or cf_root/lib directory.

  5. To change to use a different Verity Locales package (for example, English), repeat this procedure for the new Verity Locales package.


ColdFusion MX directory structure

The following table describes the directories under the cf_root directory:

Directory | Description
bin | Programs for starting, stopping, and viewing information for ColdFusion MX, and to run Crystal Reports (Windows only).
cache | Repository for temporary files from ColdFusion MX.
cfx | Sample C++ and Java CFX files with their supporting files. You can also store your CFX files in this directory (although you can put them in any location that is defined in your classpath).
charting | Files for the ColdFusion MX graphing and charting engine.
Custom Tags | Repository for your custom tags.
db | On Windows, the files for sample Microsoft Access databases and ODBC services. On UNIX, the files for the sample Pointbase databases.
jintegra | JIntegra programs, libraries, and other supporting files (for example, to integrate Java and COM code; manage access to ActiveX controls (OCXs) that are hosted in a graphical user interface (GUI) container; and register the JVM and type libraries).
jre | (UNIX only) Files for the Java Runtime Environment (JRE) that is bundled with ColdFusion MX for your UNIX distribution. On Windows, the files for the bundled JRE are in \runtime\jre.
lib | JAR, XML, property, and other files that constitute the foundation of ColdFusion MX, for functionality such as queries, charting, mail, security, Verity searches, and system probes.
logs | Repository for ColdFusion MX log files. JRE-specific log files are in the runtime\logs directory.
Mail | Repository for spooled mail and mail that cannot be delivered.
META-INF | XML metadata for the ColdFusion Administrator.
registry | (UNIX only) Flat file to store registry settings (this file will be obsolete in future versions of ColdFusion MX).
runtime | Programs and supporting files for the ColdFusion MX runtime. On Windows, the files for the bundled JRE are in runtime\jre.
uninstall | (UNIX only) Files to uninstall ColdFusion MX from UNIX.
verity | Verity collections. (The Verity program files are in the lib directory.)
wwwroot | Default web root directory for the standalone web server. When running on other web servers, this directory contains only the WEB-INF directory; do not remove this directory.


Using the ColdFusion MX web server

ColdFusion MX has its own web server that you can use to develop ColdFusion MX applications, without depending on an external web server, such as Internet Information Server (IIS), Apache, or iPlanet. Macromedia does not recommend using the ColdFusion MX web server in a production environment. However, it is more than suitable for development, allowing you to create virtual directories and set the default document (for example, default.cfm or index.cfm).

During the ColdFusion MX installation, you must choose a web server. If you select the Standalone server in Windows, or the Internal (Port Based) server in UNIX, then your web root directory is located in the ColdFusion MX application directory (the default is c:\CFusionMX\wwwroot for Windows and /opt/coldfusionmx/wwwroot for UNIX). By default, the web server runs on port 8500. This means that to display a page in your application, you must append :8500 to the host name or IP address in the URL; for example, http://localhost:8500/YourApp1/index.cfm. (If the page still does not display, make sure that the document is located in the ColdFusion MX web root directory; for example, c:\cfusionmx\wwwroot\MyApp.cfm.)


Switching the port for the ColdFusion MX web server

You can change the default port on which the ColdFusion MX web server runs.

To change the default port for the ColdFusion MX web server:

  1. Back up the jrun.xml file.

    2. This file is in the cf_root\runtime\servers\default\SERVER-INF directory in Windows, and in the cf_root/runtime/servers/default/SERVER-INF directory in UNIX.

  2. Open the original jrun.xml file for editing.
  3. Change the port in the following node (near the bottom of the file):
    4. <service class="jrun.servlet.http.WebService" name="WebService">
   <attribute name="port">8500</attribute>
   <attribute name="interface">*</attribute>
</service>
  4. Save the file.
  5. Restart ColdFusion MX.


Switching from another web server

You can switch to the built-in ColdFusion MX web server without reinstalling, even if you did not select it during installation. To run the ColdFusion Administrator, copy the contents of your web root directory to the ColdFusion MX cf_root\wwwroot or cf_root/wwwroot directory, and use an appropriate URL reference (for example, http://localhost:8500/YourApp1/index.cfm).

To switch to another web server, follow the instructions for the appropriate web server on your platform in Configuring web servers.


Uninstalling ColdFusion MX

The steps for uninstalling ColdFusion MX depend on your operating system. This section contains instructions for Windows and UNIX.


Uninstalling ColdFusion MX from Windows

Uninstalling ColdFusion MX deletes all program files and related components from your computer.

To uninstall ColdFusion MX from Windows:

  1. Select Start > Settings > Control Panel > Add/Remove Programs > ColdFusion MX.
  2. Click Remove, then Next.

    3. A dialog box displays to confirm that you want to uninstall.

  3. To begin uninstalling, click Yes.
  4. When the program completes, restart your computer.

ColdFusion MX is deleted from your server.


Uninstalling ColdFusion MX from UNIX

Uninstalling ColdFusion MX deletes all program files and related components from your computer.

To uninstall ColdFusion MX from UNIX:

  1. Log in as root.
  2. Enter the following command to go to the cf_root\uninstall directory:
    3. cd cf_root/uninstall
  3. Enter the following command:
    4. ./uninstall.sh

ColdFusion MX is deleted from your server.

Previous


Configuring your System

This chapter describes how to manage ColdFusion MX services and processes, how to configure web servers manually, and how to change user accounts and configure databases for ColdFusion MX.

Note: In this chapter, cf_root refers to your installation directory. By default this directory is c:\CFusionMX in Windows, and /opt/coldfusionmx in UNIX.

Contents
  • Overview of configuration tasks
  • Managing ColdFusion MX
  • Configuring web servers
  • Enabling CORBA support
  • Disabling Remote Development Services (RDS)
  • Changing the ColdFusion MX user account in Windows
  • Connecting to an external JDBC Type 4 data source
Next


Overview of configuration tasks

The following table describes when to do the configuration tasks that are documented in this chapter:

Configuration task | When to do it
Managing ColdFusion MX | You must stop and restart ColdFusion MX after you enable or disable security in the ColdFusion Administrator or change any of the Java and JVM settings, in order for your changes to take effect. You can do this at any time after you install ColdFusion MX.
Configuring web servers | For an external web server, do this after you install ColdFusion MX and before you send anything to your web server for rendering. You do not need to do this if you use the built-in ColdFusion MX web server.
Enabling CORBA support | You must do this only if you need to make CORBA invocations from ColdFusion MX. You can do this after you install ColdFusion MX and before you make a CORBA call from ColdFusion MX.
Disabling Remote Development Services (RDS) | For security reasons, disable RDS in a production environment, after you install ColdFusion MX and before you deploy your application.
Changing the ColdFusion MX user account in Windows | You must do this only if you discover that the account under which ColdFusion MX is running has inappropriate access rights; for example, to interact with remote data sources, other application pages, or COM objects. You can do this after you install ColdFusion MX and before you deploy your application.
Connecting to an external JDBC Type 4 data source | You must do this only if you use a Type 4 database driver that is not included in ColdFusion MX. You can do this after you install ColdFusion MX and before you set up the data source in the ColdFusion Administrator.

For information about additional configuration tasks, see Administering ColdFusion MX.


Managing ColdFusion MX

The ColdFusion MX installation creates a few services in Windows and a single process in UNIX. The following sections describe how to manage them:

  • Managing ColdFusion MX services in Windows
  • Managing the ColdFusion MX process in UNIX


Managing ColdFusion MX services in Windows

This section describes the ColdFusion MX services and explains how to manage them. It also describes how to run ColdFusion MX in Windows 98/ME, which does not use services in its architecture.


Overview of services

The ColdFusion MX installation creates the following services in Windows NT, Windows 2000, Windows XP:

Service | Purpose
ColdFusion MX Application Server | The main ColdFusion service. ColdFusion pages cannot be processed if this service is not running.
ColdFusion MX ODBC Agent | The service used to configure data sources for the ColdFusion MX ODBC Server.
ColdFusion MX ODBC Server | The middle-tier service for ODBC connections that use the ColdFusion MX DataDirect drivers for Microsoft Access and ODBC Socket.


Starting and stopping services

In the ColdFusion Administrator, if you enable or disable security or change any option in the Java and JVM Settings page, you must stop and restart ColdFusion MX for your changes to take effect.

To start or stop a ColdFusion service:

  1. Open the Services dialog box:
  2. In Windows NT 4.0, select Start > Settings > Control Panel > Services.
  3. In Windows 2000 or Windows XP, select Start > Settings > Control Panel > Administrative Tools > Services.
  4. For other Windows platforms, see the Windows online Help.

    5. If a service is running, its status appears as Started in the Status column. If it is not running, no status appears for the service.

  5. Do one of the following:
  6. Right-click a service and select Stop.

    7. In Windows NT, click Yes to confirm that you want to stop the service.

  7. Right-click a service and select Start.
  8. Right-click a service and select Restart.

    9. The Services window refreshes.

To set ColdFusion MX to start automatically or manually:

  1. Open the Services dialog box:
  2. In Windows NT 4.0, select Start > Settings > Control Panel > Services.
  3. In Windows 2000 and Windows XP, select Start > Settings > Control Panel > Administrative Tools > Services.
  4. For other Windows platforms, see the Windows online Help.
  5. Do one of the following:
  6. In Windows NT, double-click the service that you want to configure.

    7. The dialog box for the service opens.

    Do the following step in the Startup Type frame.

  7. In Windows 2000 or Windows XP, right-click the service that you want to configure and select Properties.

    8. In the Properties dialog box, click the General tab.

    Do the following step in the Startup Type drop-down list box.

  8. Select one of the following options:
  9. Automatic Starts the service automatically when you start the computer.
  10. Manual Requires a user or dependent service to manually start the service.
  11. Click OK.


Running ColdFusion MX in Windows 98/ME

Since Windows 98 and Windows ME do not have a services architecture, ColdFusion MX runs as executable files. The following table describes these executable files:

Executable file | Purpose
ColdFusion Application Server | The main ColdFusion program. ColdFusion pages cannot be processed if this program is not running.
ColdFusion RDS | The program that provides security, directory and file browsing, and debugging services for Remote Development Services (RDS), which lets you access ColdFusion MX from Dreamweaver MX, HomeSite+, and ColdFusion Studio.

When ColdFusion MX is running, two icons appear in the task bar. To stop the ColdFusion Application Server executable, right-click the IDE service icon and select Stop. To run ColdFusion MX at startup, place a shortcut for the ColdFusion MX icon in the Startup program group. For instructions, see the Windows online Help.


Managing the ColdFusion MX process in UNIX

This section describes the ColdFusion MX process and explains how to manage it.


Overview of the ColdFusion MX process

The ColdFusion MX installation creates a single process in UNIX called cfusion. To check whether it is running, use the following command:

ps -eaf | grep cfusion

If it is running, your computer returns something similar to the following line:

nobody 4528 1 10 12:44 pts/0 00:00:07 /opt/coldfusionmx/runtime/bin/cfusion -start


Managing the process

The ColdFusion MX process starts automatically when you start your computer and shuts down automatically when you shut down your computer.

In various situations, you might choose to manually stop and start or restart the ColdFusion MX process. However, if you enable or disable security or change any option in the Java and JVM Settings page in the ColdFusion Administrator, you must stop and restart ColdFusion MX for your changes to take effect.

To manage the ColdFusion MX process in UNIX:

  1. Log in as root, if you have not already done so.
  2. Enter the following command:
    3. cd cf_root/bin
  3. Enter the appropriate command for what you need to do, as described in the following table:

    Task
    Command to enter
    Start ColdFusion MX
    coldfusion start
    Stop ColdFusion MX
    coldfusion stop
    Restart ColdFusion MX
    coldfusion restart
    View performance information for ColdFusion MX
    coldfusion status


Configuring web servers

This section describes how to configure a web server to serve ColdFusion pages, for Windows and UNIX. Do this if you did not configure a web server automatically during installation, or to change your web server.

Note: If you cannot verify your configuration, repeat the procedure. If the problem persists, contact Macromedia Technical Support for assistance, or manually create the element that you cannot verify in the configuration (for example, manually add an entry to the Apache web server properties file, as documented in this section).


Configuring web servers in Windows

This section explains how to configure the following web servers in Windows:

  • Configuring Internet Information Server (IIS)
  • Configuring Netscape Enterprise or iPlanet web server
  • Configuring Apache web server


Configuring Internet Information Server (IIS)

This section describes how to configure Internet Information Server (IIS) for ColdFusion MX on Windows, and how to verify your configuration.

Note: The Macromedia ColdFusion MX team has tested integration with the .Net Framework version 1 and Service Pack 1.

To configure IIS for ColdFusion MX on Windows:

  1. Select Start > Run, and enter cmd.
  2. At the command prompt, enter the following command on a single line:
    3. cf_root\runtime\jre\bin\java -cp cf_root\runtime\lib
-jar cf_root\runtime\lib\wsconfig.jar -ws IIS -site "0"
-map .cfm,.cfc,.cfml,.jsp -v

    Note: You must enter the previous command as a single (long) line.

The following is a sample command:

c:\cfusionmx\runtime\jre\bin\java -cp c:\cfusionmx\runtime\lib
-jar c:\cfusionmx\runtime\lib\wsconfig.jar -ws IIS -site "0"
-map .cfm,.cfc,.cfml,.jsp -v

This adds the appropriate IIS application mappings for ColdFusion MX.

If necessary, ColdFusion MX generates the following log file for errors: cf_root\runtime\lib\wsconfig\wsconfig.log.

To verify your IIS configuration:

  1. Verify that the following file was created: cf_root/runtime/lib/wsconfig/jrun.dll.
  2. For each of your IIS websites, verify that application mappings for .cfm, .cfml, .cfc, and .jsp were added, as follows:
    1. In IIS, right-click an IIS website and select Properties.
    2. In the Properties dialog box, on the Home Directory tab, click Configuration.
    3. In the Application Configuration dialog box, click the App Mappings tab.

      4. The new application mappings appear, as the following figure shows:

      This is a picture of the feature being described.

  3. Verify that each of your IIS websites has a virtual directory called JRunScripts.

    4. The following figure shows a sample JRunScripts virtual directory:

    This is a picture of the feature being described.

  4. Verify that the JRunScripts directory in each of your IIS websites points to the correct location, as follows:
    1. Right-click the JRunScripts directory and select Properties.
    2. In the Properties dialog box, on the Virtual Directories tab, verify that the Local Path text box contains the following path:

      3. cf_root/runtime/lib/wsconfig/1/

      The following figure shows a sample Properties dialog box for the JRunScripts virtual directory:

      This is a picture of the feature being described.


Configuring Netscape Enterprise or iPlanet web server

This section describes how to configure Netscape Enterprise web server 3.6x or iPlanet web server (4.x or 6.x) for ColdFusion MX on Windows, and how to verify your configuration.

To configure Netscape or iPlanet for ColdFusion MX on Windows:

  1. Select Start > Run, and enter cmd.
  2. At the command prompt, enter the following command on a single line:
    3. cf_root\runtime\jre\bin\java -cp cf_root\runtime\lib
-jar cf_root\runtime\lib\wsconfig.jar -ws <Iplanet or NES>
-dir <Netscape/iPlanet config directory> -v

    Note: You must enter the previous command as a single (long) line.

The following is a sample command:

c:\cfusionmx\runtime\jre\bin\java -cp c:\cfusionmx\runtime\lib
-jar c:\cfusionmx\runtime\lib\wsconfig.jar -ws NES
-dir c:\netscape\server4\https-yourserver\config -v

To verify your Netscape or iPlanet configuration:

  1. Verify that the following file was created:
    cf_root\runtime\lib\wsconfig\1\jrun_nsapi35.dll
  2. Open the Netscape configuration file, obj.conf, in the web server directory (for example, in c:\netscape\server4\https-yourserver\config\obj.conf).
  3. Verify that the following line was added to the file:
    4. NameTrans fn="jrunfilter"
  4. Verify that #JRun prefixes the following NameTrans line in the file:
    5. #JRun NameTrans fn="pfx2dir" from="/servlet"
dir="e:/netscape/servers/docs/servlet"
  5. Verify that the following object element is at the end of the file:
    6. <Object name="jrun">
PathCheck fn="jrunfilter"
Service fn="jrunservice"
</Object>


Configuring Apache web server

This section describes how to configure the Apache web server for ColdFusion MX on Windows, and how to verify your configuration.

To configure Apache for ColdFusion MX on Windows:

  1. Select Start > Run, and enter cmd.
  2. At the command prompt, enter the following command on a single line:
    3. cf_root\runtime\jre\bin\java -cp cf_root\runtime\lib
-jar cf_root\runtime\lib\wsconfig.jar -ws Apache
-dir <Apache conf directory> -v

    Note: You must enter the previous command as a single (long) line.

The following is a sample command:

c:\cfusionmx\runtime\jre\bin\java -cp c:\cfusionmx\runtime\lib
-jar c:\cfusionmx\runtime\lib\wsconfig.jar -ws Apache
-dir c:\Program Files\Apache Group\Apache\conf -v

To verify your Apache configuration:

  1. Verify that the following file was created:
    cf_root\runtime\lib\wsconfig\1\mod_jrun.so
  2. Open the Apache configuration file, httpd.conf, in your Apache conf directory. By default it is c:\Program Files\Apache Group\Apache\conf\httpd.conf.

    3. Verify that the following code was appended to this file:

    # JRun Settings
LoadModule jrun_module "c:/CFusionMX/runtime/lib/wsconfig/1/mod_jrun.so"
<IfModule mod_jrun.c>
    JRunConfig Verbose false
    JRunConfig Apialloc false
    JRunConfig Ssl false
    JRunConfig Serverstore "c:/CFusionMX/runtime/lib/wsconfig/1/
jrunserver.store"
    JRunConfig Bootstrap 127.0.0.1:51000
    #JRunConfig Errorurl <optionally redirect to this URL for errors>
</IfModule>


Configuring web servers in UNIX

This section explains how to configure the following web servers in UNIX:

  • Configuring Apache web server
  • Configuring Netscape or iPlanet web server


Configuring Apache web server

This section describes how to configure the Apache web server for ColdFusion MX on UNIX, and how to verify your configuration.

To configure Apache for ColdFusion MX on UNIX:

  • Enter the following command on a single line:
    • cf_root/jre/bin/java -jar cf_root/runtime/lib/wsconfig.jar -ws Apache
-dir <apache config directory> -v

    Note: You must enter the previous command as a single (long) line.

The following is a sample command:

/opt/coldfusionmx/jre/bin/java -jar /opt/coldfusionmx/runtime/lib/wsconfig.jar
-ws Apache -dir /etc/httpd/conf -v

    Note: For unique configurations, add the -bin and -script parameters.

To verify your Apache configuration:

  1. Verify that the following file was created:
    cf_root/runtime/lib/wsconfig/1/mod_jrun.so
  2. Open the Apache configuration file, httpd.conf, in your Apache conf directory. By default it is /etc/httpd/conf/httpd.conf.

    3. Verify that the following code was appended to this file:

    # JRun Settings
LoadModule jrun_module "/opt/coldfusionmx/runtime/lib/wsconfig/1/mod_jrun.so"
<IfModule mod_jrun.c>
    JRunConfig Verbose false
    JRunConfig Apialloc false
    JRunConfig Ssl false
    JRunConfig Serverstore "/opt/coldfusionmx/runtime/lib/wsconfig/1/
jrunserver.store"
    JRunConfig Bootstrap 127.0.0.1:51000
    #JRunConfig Errorurl <optionally redirect to this URL for errors>
</IfModule>


Configuring Netscape or iPlanet web server

This section describes how to configure Netscape Enterprise web server 3.6x or iPlanet web server (4.x or 6.x) for ColdFusion MX on UNIX, and how to verify your configuration.

To configure Netscape or iPlanet for ColdFusion MX on UNIX:

  • Enter the following command on a single line:
    • cf_root/jre/bin/java -jar cf_root/runtime/lib/wsconfig.jar
-ws <Iplanet or NES> -dir <Netscape/iPlanet config directory> -v

    Note: You must enter the previous command as a single (long) line.

The following is a sample command:

/opt/coldfusionmx/jre/bin/java
-jar /opt/coldfusionmx/runtime/lib/wsconfig.jar
-ws NES -dir /usr/netscape/server4/https-surf/config -v

To verify your Netscape or iPlanet configuration:

  1. Verify that the following file was created:
    cf_root/runtime/lib/wsconfig/1/jrun_nsapi35.dll
  2. Open the Netscape configuration file, obj.conf, in the web server directory (for example, in /usr/netscape/server4/https-surf/config/obj.conf).
  3. Verify that the following line is in the file:
    4. NameTrans fn="jrunfilter"
  4. Verify that #JRun prefixes the following NameTrans line in the file:
    5. #JRun NameTrans fn="pfx2dir" from="/servlet"
dir="e:/netscape/servers/docs/servlet"
  5. Verify that the following object element is at the end of the file:
    6. <Object name="jrun">
PathCheck fn="jrunfilter"
Service fn="jrunservice"
</Object>


Enabling CORBA support

ColdFusion MX supports third-party Object Request Brokers (ORBs) through its integration with Borland Visibroker. However, you must acquire the Common Object Request Broker Architecture (CORBA) software separately from Borland.

This section describes the system requirements for enabling CORBA support, and explains how to install and configure Visibroker to work with ColdFusion MX.


System requirements

You must have all of the following components installed on your computer before you can make CORBA invocations from ColdFusion MX:

  • Borland Visibroker 4.5.1 for Java
  • Java Runtime Environment (JRE) 1.2 for the Visibroker Interface Repository
  • JRE 1.3 or later for ColdFusion MX (this JRE is installed with ColdFusion MX)


Installing Visibroker for CORBA connections

To install Visibroker for CORBA connections:

  1. Install Visibroker on the CORBA server side, if you have not already done so.

    2. For more information, see the Borland Visibroker documentation.

  2. Add the vbjorb.jar file to the ColdFusion MX classpath, as follows:
    1. In the ColdFusion Administrator, select Server Settings > Java and JVM.
    2. On the Java and JVM Settings page, in the Class Path text box, enter the path to your vbjorb.jar file (for example, c:\Inprise\vbroker\lib\vbjorb.jar).

      3. (You only need the jar file on the computer that is running ColdFusion MX; you do not need the full Visibroker installation.)

    3. Click Submit Changes.
  3. Configure a Visibroker connector in ColdFusion MX, as follows:
    1. In the ColdFusion Administrator, select Extensions > CORBA Connectors.
    2. In the CORBA Connectors page, click Register CORBA Connector.
    3. In the CORBA Connector page, enter information for the connector.

      4. The following is an example of a correctly configured connector:

      Field | Value
ORB Name | visibroker
ORB Class Name | coldfusion.runtime.corba.VisibrokerConnector
Classpath | (none)
ORB Property File | c:\CFusionMX\lib\vbjorb.properties

      The ORB Property File points to a Java properties file that contains the correct ORB settings for Visibroker.

      The contents of the vbjorb.properties file look like the following:

          org.omg.CORBA.ORBClass=com.inprise.vbroker.orb.ORB
    org.omg.CORBA.ORBSingletonClass=com.inprise.vbroker.orb.ORB
    SVCnameroot=namingroot
    4. When you finish editing the page, click Submit.

      5. The CORBA Connectors page appears.

    5. Select the radio button to the left of your new CORBA connector and click Select ORB Connector.

      6. This sets the new connector to be the default.

  4. Prepare your CORBA server side, as follows:
    1. Start your Visibroker osagent service or process, if it is not already running, by entering the following command:
      2.     osagent

Note: If you must connect to an osagent in another subnetwork, include the following lines in the vbjorb.properties file:

   vbroker.agent.addr=<IP address of machine running OSAGENT>
   vbroker.agent.port=<port>
    2. Start the Interface Repository and load it with the IDL file that you plan to use, by entering an irep command, as in the following example:
      3.     irep myir MyIDLFile.idl
    3. If you plan to use the Naming Service, start it by entering a command like the following:
      4.     nameserv namingroot

Note: The name of the Naming Service (namingroot in the previous example) must match the value for SVCnameroot in the vbjorb.properties file.
    4. Start Visibroker on your CORBA server.

      5. For more information, see the Borland Visibroker documentation.

  5. Restart ColdFusion MX for your changes to take effect.

    6. For more information, see Managing ColdFusion MX.

You can now make CORBA invocations from ColdFusion MX. For more information about integrating CORBA objects into ColdFusion MX, see Developing ColdFusion MX Applications with CFML.


Disabling Remote Development Services (RDS)

If you use Dreamweaver MX, HomeSite+, or ColdFusion Studio to develop your applications, you can access a remote ColdFusion MX server using HTTP. However, you must configure Remote Development Services (RDS) in your integrated development environment (IDE), and you must enable RDS in the ColdFusion MX server (which it is by default). Using RDS, IDE users can securely access remote files and data sources, build SQL queries from these data sources, and debug CFML code.

However, for security reasons, Macromedia recommends that you disable RDS on a production server. To disable it, you must disable the RDSServlet mapping.

To disable the RDSServlet mapping:

  1. Back up the web.xml file.

    2. This file is in the cf_root\wwwroot\WEB-INF directory on Windows and in the cf_root/wwwroot/WEB-INF directory on UNIX.

  2. Open the original web.xml file for editing.
  3. Comment out the RDSServlet mapping, as shown in the following example:
    4. <!--
<servlet-mapping>
<servlet-name>RDSServlet</servlet-name>
<url-pattern>/CFIDE/main/ide.cfm</url-pattern>
</servlet-mapping>
-->
  4. Save the file.
  5. Restart ColdFusion MX.

    6. For more information, see Starting and stopping services for Windows, or Managing the process for UNIX.

RDS is disabled on the ColdFusion MX Server.


Changing the ColdFusion MX user account in Windows

If you discover that the user account under which ColdFusion MX runs has an inappropriate level of access--for example, to interact with remote data sources, other application pages, and COM objects--you should change the user account.

Note: For Windows NT, select Services from the Control Panel and use the following procedure as a guideline.

You cannot do this procedure on Windows 98 and Windows ME because they do not use services in their architecture.

To change the ColdFusion MX user account:

  1. Select Start > Run.
  2. In the Run dialog box, enter mmc in the Open text box and click OK.

    3. The Microsoft Management Console (MMC) appears for a new console, labeled Console1, as the following figure shows:

    This is a picture of the feature being described.

  3. Select Console > Open.
  4. In the Open dialog box, browse to compmgmt.msc, the Computer Management console file (usually located in the system or system32 directory). Click Open.

    5. The MMC for Computer Management appears, as the following figure shows:

    This is a picture of the feature being described.

  5. On the Tree tab, under Services and Applications, click Services.

    6. All of the services for your computer appear in the right pane.

  6. Right-click ColdFusion MX Application Server and select Properties.

    7. The ColdFusion MX Application Server Properties (Local Computer) dialog box appears, as the following figure shows:

    This is a picture of the feature being described.

  7. On the Log On tab, select This account, and enter the account information.
  8. Click OK.
  9. In the MMC with the services displayed in the right pane, right-click ColdFusion MX Application Server and select Restart.

Caution:Do not rename your Windows Administrator account. This will cause problems with security policies and profiles.


Connecting to an external JDBC Type 4 data source

ColdFusion MX includes JDBC Type 4 database drivers from Merant, and JDBC Type 3 database drivers from Merant and SQL Link. (JDBC is an Application Programming Interface (API) for Java programs to access data.)

To use a JDBC driver that is not included with ColdFusion MX (such as SQLAnywhere, MySQL, or PostGreSQL) you must configure it and add a data source for it.

To connect to an external JDBC data source:

  1. Copy the database driver file to a directory other than the cf_root directory.
  2. In the ColdFusion Administrator, open the Java and JVM Settings page.
  3. In the Class Path text box, enter the directory that contains the driver file and click Submit Changes.
  4. Restart ColdFusion MX.

    5. For more information, see Managing ColdFusion MX.

    Note: On Windows, make sure that you restart all of the ColdFusion MX services; these are listed in Overview of services.

  5. In the ColdFusion Administrator, add the other JDBC Type 4 data source, selecting Other from the Driver drop-down list box.

    6. For more information, see the “Data Source Management” chapter of Administering ColdFusion MX.

You can now connect to an external JDBC Type 4 data source.

Previous


About This Book

Getting Started Building ColdFusion Applications is intended for anyone who wants to learn how to use ColdFusion MX to create web applications.

Contents
  • Developer resources
  • About Macromedia ColdFusion MX documentation
  • Getting answers
  • Contacting Macromedia
Next


Developer resources

Macromedia, Inc. is committed to setting the standard for customer support in developer education, documentation, technical support, and professional services. The Macromedia website is designed to give you quick access to the entire range of online resources. The following table shows the locations of these resources:

Resource | Description | URL
Macromedia website | General information about Macromedia products and services | http://www.macromedia.com
Information on ColdFusion | Detailed product information on ColdFusion and related topics | http://www.macromedia.com/coldfusion
Macromedia ColdFusion Support Center | Professional support programs that Macromedia offers | http://www.macromedia.com/support/coldfusion
ColdFusion Online Forum | Access to experienced ColdFusion developers through participation in the Online Forums, where you can post messages and read replies on many subjects relating to ColdFusion | http://webforums.macromedia.com/coldfusion/
Installation Suppor | Support for installation-related issues for all Macromedia products | http://www.macromedia.com/support/email/isupport
Training | Information about classes, on-site training, and online courses offered by Macromedia | http://www.macromedia.com/support/training
Developer Resources | All the resources that you need to stay on the cutting edge of ColdFusion development, including online discussion groups, Knowledge Base, technical papers, and more | http://www.macromedia.com/desdev/developer/
Reference Desk | Development tips, articles, documentation, and white papers | http://www.macromedia.com/v1/developer/TechnologyReference/index.cfm
Macromedia Alliance | Connection with the growing network of solution providers, application developers, resellers, and hosting services creating solutions with ColdFusion | http://www.macromedia.com/partners/


Introducing ColdFusion MX

This chapter introduces the core technologies that are the foundation for Macromedia ColdFusion MX. It provides a basic understanding of the Internet, web servers, URLs, HTML, and JavaScript. In addition, it introduces the basic concepts about ColdFusion MX, how it works, and the various components that comprise it.

Contents
  • The Internet and related technologies
  • Understanding web application servers
  • What is ColdFusion MX?
  • Using ColdFusion MX with Macromedia Flash MX
Next


The Internet and related technologies

ColdFusion MX is tightly integrated with the Internet and the World Wide Web. For a better understanding of ColdFusion MX, the following sections provide a basic description about the Internet and its related technologies.


The Internet

One way to think of the Internet is to picture it as a wide-area network that spans multiple geographic locations. Each location in this enormous network is comprised of a group of computers that are relatively close in proximity to each other and are connected by hardware and cabling.

Users communicate from one location to another using a communication protocol known as IP (Internet Protocol). This protocol, running on each computer connected to the Internet, ensures that communication breakdowns do not occur and that the networked computers can communicate and exchange data properly with each other.

Every computer connected to the Internet has a unique IP address. If duplicate IP addresses existed, information using a given address could end up in the wrong place. It would be like using the same street address for two residences. As a sender of information, you would never know if the intended receiver did receive your information.


Internet applications

Software applications that run on the Internet are known as Internet applications. The following table lists some of the most popular Internet applications:

Application
Description
WWW
World Wide Web. The web is a hypertext information system. It lets you read and navigate to text and visual information in a nonlinear way that is based on what you want to read next. This freely available information is linked together in various ways on the Internet and is available for you to browse whenever you want.
A website is a location on the World Wide Web. When you view a page, your browser connects to that website to get the information.
E-mail
Electronic mail. E-mail programs, such as Microsoft Outlook, let you send and receive mail electronically over the Internet.
FTP
File Transfer Protocol. This protocol lets you transfer information between hosts using an FTP site.
Telnet
Telnet lets you log on to a computer from a remote location.
NFS
Network File System. NFS lets you share files between hosts.

Internet applications communicate across the Internet by using IP. IP transmits application data in small packets to a destination IP address. The receiving host processes the information that it receives.


Intranet applications

An intranet is a private LAN (Local Area Network) or WAN (Wide Area Network) that lets you use and interact with your Internet-based applications in a secure environment. These private networks exist in large corporations, small companies, and even home offices. Private networks let companies and organizations determine who can share their information and who can access it.

An intranet application is an application that works on a private intranet (network). It differs from an Internet application only in who can access it and the location of the client computer accessing it. An intranet application can also operate over a public Internet. When an intranet application runs on the Internet, the application is called an Internet application. These terms, Internet applications and intranet applications, are used interchangeably throughout this book.


Web servers

A web server is a software program that serves web pages to requesting clients. The web server software runs on any computer. Often people refer to the host running the web-server software as the web server, and think of it as the hardware. However, technically, the web server is just the software program and not the hardware.


How a web server and connecting hosts communicate

When a user at a specific IP address requests a file, the web server retrieves that file and returns it to the requesting IP address. The contents of a file are not important to the web server. It is the web browser that makes the request and interprets and displays the data in the file that was returned from the web server.

When you make a request from a web server, an IP connection is made across the Internet between the client making the request and the host running the web-server software. As soon as a request is satisfied by the web server, the Internet connection between the client and the host breaks. A page containing images or links to other pages all require separate connections. Often, it takes many requests to retrieve all the information on one web page.


Web pages

The information on the World Wide Web is presented in web pages. You can create web pages using a series of client-side technologies. A web page can include a variety of information: text, lists, forms for capturing data, tables for presenting data, scripts that perform a function, multimedia content that animate pages, and so on.

No matter the content of the web page, the web browser must process and display the page.


Web browsers

A web browser is a software program residing on a computer that you use to view pages on and navigate the World Wide Web. When you use a browser to request a page on a website, that browser is making a web connection to a web server.

As mentioned previously, the web browser processes the web pages that it receives from a web server and displays the pages to the user. Depending on the browser that you use and the features it includes, you might be able to play multimedia files, view and interact with Java applets, read your e-mail, or use other advanced features.

Some of the most popular web browsers today are Microsoft Internet Explorer, Netscape Navigator, and Mozilla. Unfortunately, most browsers today parse web pages differently. Web designers must pay special attention to the way a browser behaves, or users might not see the pages as the designers intended. Therefore, web designers test their pages on multiple browsers before publishing them on their website.


HTML

Web page authors create plain text files using the Hypertext Markup Language. This language, known as HTML, consists of a series of simple-to-learn tags. You can use these tags to mark up a page of text. Tags can indicate page elements, structure, formatting, hypertext links to other locations, and so on. Web browsers read the HTML tags and format the text and styles that appear on the computer screen.

HTML tags usually have a starting and ending tag, surrounding the text that they affect. The starting tag turns on a feature (heading, bold, and so on), and the ending tag turns it off. All ending tags have a forward slash (/) preceding the tag name.

Most HTML tags look like this:

<TheTagName>text</TheTagName>

The tag name is always enclosed in angle brackets (<>) and is case-insensitive, which means that you can specify the tag name in uppercase, lowercase, or mixed case.

Most web browsers let you view the source of an HTML page. This option is usually located in a menu or a button.


JavaScript

Web developers write JavaScript to create small programs that run in the browser. JavaScript is one of the most popular client-side scripting languages today. It is supported by almost all browsers on the market. Web developers use JavaScript to do these actions:

  • Validate user actions.
  • Create scrolling messages in a browser’s status bar.
  • Animate text or images.

JavaScript can be inserted in the HTML file. HTML uses tags to mark the start and end of the code. The <script> tag tells the browser that the following chunk of text, bounded by the closing </script> tag, is not HTML, but rather script code to be processed.

Although using JavaScript seems much like inserting HTML content, JavaScript is more difficult to learn than HTML. For more information about JavaScript, see any JavaScript primer.


URLs

Every piece of information on the World Wide Web has a unique address. This address is called a Uniform Resource Locator, or URL. A URL is a pointer to some bit of data on the web. This information might include a web document, a file on a FTP site, a posting on Usenet, or even an e-mail address. URLs contain information about the following:

  • How to get the information (what protocol to use: FTP, HTTP, and so on)
  • The Internet host name to contact (for example, www.macromedia.com; http://localhost/mysite; or ftp.mysite.com)
  • The directory or other location to locate the requested information

In addition, you use special URLs to send e-mail and for using the Telnet program.


Understanding web application servers

As explained previously, web browsers make requests, and web servers fulfill those requests by returning the requested information to the browser. This information is usually HTML files, as well as other types.

When you think about it, web servers capabilities are limited because all they do is wait for requests to arrive and attempt to fulfill those requests as soon as possible. Web servers do not let you do the following tasks:

  • Interact with a database.
  • Serve up customized information based on user preferences or requests.
  • Validate user actions.

Web servers, basically, locate information and return that information to a web browser.

To extend the capabilities of a web server, you need a web application server. A web application server is a software program that lets the web server do more tasks, like those listed in the previous paragraph.


How a web server and web application server work together

The following steps explain how a web server processes a page that also needs processing by a web application server:

  1. The user requests a page by typing a URL in a browser, and the web server receives the request.
  2. The web server looks at the MIME type (or file extension) to determine whether a web application server must process the page. Then one of the following actions occur:
  3. If the MIME type indicates that the file is a simple web page (typically an HTM extension), then the web server fulfills the request and sends the file to the browser.
  4. If the MIME type indicates that the requested file is a page that a web application server must process (CFM or CFC extension for ColdFusion requests), then the web server passes it to the web application server. The web application server processes the page and sends the results to the web server, which returns those results to the browser. The following figure shows this process:

This is a picture of the feature being described.

Web application servers process code in a page that a browser and web server cannot interpret. The web server recognizes these requested pages by the file extension and forwards it to the web application server for action. The web application server interprets the programming instructions in the page and generates output that a web browser can interpret. Then the web server returns the output to the browser.

By using a web application server, web developers can build highly interactive and data-rich sites, such as the following:

  • Create shopping carts and e-commerce sites.
  • Query other database applications for data.
  • Dynamically populate form elements.
  • Respond with e-mail immediately after a user submits a form.


What is ColdFusion MX?

ColdFusion MX is a powerful web application server that lets you create robust sites and applications without a long learning curve. ColdFusion MX does not require coding in traditional programming languages (for example, C/C++, Java, XML), although it supports these traditional programming languages.

ColdFusion MX consists of the following core components:

  • ColdFusion application server
  • ColdFusion Markup Language (CFML)
  • ColdFusion Administrator

The following sections describe these core components in more detail.


The ColdFusion application server

The ColdFusion application server is a software program that resides on the same computer as your web server software. It is the program that parses (reads and interprets) and processes supplied instructions. These instructions are passed to ColdFusion through ColdFusion pages, which use a CFM or CFC file extension. A ColdFusion page looks like an HTML page but contains special tags that instruct the ColdFusion server to perform specific operations.


How ColdFusion processes pages

The following steps explain how the ColdFusion server processes a ColdFusion page:

  1. The ColdFusion server looks at the content of the page and searches for the following ColdFusion instructions:
  2. Tags that begin with cf.
  3. Variables and functions that are always surrounded by pound signs (#).
  4. If the Coldfusion server finds any HTML or plain text in the page, the ColdFusion server returns it to the web server untouched.
  5. The ColdFusion server processes all the ColdFusion instructions found, and returns any remaining results to the web server. The web server then sends the entire output to the browser.


The ColdFusion Markup Language

ColdFusion Markup Language (CFML) is a a tag-based language similar to HTML that uses special tags and functions. With CFML you can enhance your standard HTML files with database commands, conditional operators, and high-level formatting functions, and rapidly produce easy-to-maintain web applications.

CFML looks similar to HTML: it includes start and end tags, and each tag is enclosed in angle brackets. All ending tags are preceded with a forward slash (/) and all tag names are preceded with cf; for example:

<cfstarttagname> </cfendtagname>


Building applications with CFML

You build ColdFusion applications as a series of pages that use CFML. Developers can extend this language by creating their own custom tags or user-defined functions (UDF), or by integrating COM, C++, and Java components (such as JSP tag libraries).


Interacting with data sources

ColdFusion applications can interact with any database that supports a JDBC technology-based driver. A JDBC technology-based driver uses an Application Programming Language (API) to execute SQL statements to databases on most platforms. However, ColdFusion is not limited to JDBC data sources. You can also interact with existing Open Database connectivity (ODBC) data sources by using ODBC Socket, a driver that interacts with an existing ODBC driver.


Development tools

While you can code your ColdFusion application with NotePad or any HTML editor, Macromedia recommends that you build your applications using Macromedia Dreamweaver MX. Dreamweaver MX offers features and wizards that enhance ColdFusion development. For more information about Dreamweaver MX, see Configuring Your Development Environment.


The ColdFusion MX Administrator

You use the ColdFusion MX Administrator to configure and maintain the ColdFusion application server. It is a web-based application that you can access using any web browser, from any computer with an Internet connection.

This is a picture of the feature being described.

You can manage the following configuration options with the ColdFusion Administrator:

  • ColdFusion data sources
  • Debugging output
  • Server settings
  • Application security

For further details about the ColdFusion Administrator, see Installing ColdFusion MX or Administering ColdFusion MX.


Using ColdFusion MX with Macromedia Flash MX

Macromedia Flash MX is designed to overcome the many limitations of HTML and solve the problem of providing efficient, interactive, user interfaces for Internet applications. ColdFusion MX is designed to provide a fast efficient environment for developing and providing data-driven Internet applications.

By using ColdFusion MX and Flash MX together, you can easily create complete visually interactive applications for the Internet. ColdFusion MX provides a native Flash connectivity that ensures visual applications created with Flash MX can easily and securely interact with ColdFusion. Flash MX clients communicate efficiently with ColdFusion by using an Action Message Format protocol over HTTP. This protocol provides fast, lightweight, binary transfer of data between the Flash client and ColdFusion.

By using the following features of ColdFusion MX and Flash MX, you can create efficient data-driven Internet applications with visually interactive user interfaces:

  • Flash MX ActionScript commands Lets you connect to ColdFusion components (CFC) and ColdFusion pages.
  • Flash MX development application debugger Lets you trace your application logic as it executes between Flash and ColdFusion.
  • ColdFusion MX Server-Side ActionScript Lets Flash programmers familiar with ActionScript create ColdFusion services, such as SQL queries, for use by Flash clients.

For more information about using Server-Side ActionScript in ColdFusion MX, see Using Server-Side ActionScript in ColdFusion MX. For more information about developing Flash application in ColdFusion, see Developing ColdFusion MX Applications with CFML. For more information about using Flash MX, go to Macromedia on the web (www.macromedia.com).

Previous


CFML Basics

This chapter introduces the basic elements of CFML, including how to create ColdFusion pages, and use variables, functions, conditional processing, and form processing.

Contents
  • Working with ColdFusion pages
  • Understanding CFML elements
  • Working with CFML expressions
  • Understanding conditional processing
  • Processing form data
  • Commenting your code
Next


Working with ColdFusion pages

As discussed in Chapter 1, ColdFusion pages are plain text files that you use to create web applications. You can create your ColdFusion applications by writing all the code manually or by using wizards (provided with some editors) to generate the majority of the code for you.

You can use the following editors to create your ColdFusion pages:

  • Macromedia Dreamweaver MX (discussed in Chapter 4)
  • Macromedia HomeSite+ (discussed in Chapter 4)
  • Macromedia ColdFusion Studio
  • Any HTML editor
  • Windows Notepad
  • VI or EMACS (UNIX® systems)

The best choice for creating ColdFusion pages is Macromedia Dreamweaver MX. Dreamweaver MX includes many CFML features for building applications, such as rapid visual development, robust CFML editing, and integrated debugging. Dreamweaver MX also includes a copy of HomeSite+ for users who are familiar with developing their application code using ColdFusion Studio or HomeSite 5. HomeSite+ combines all the features of ColdFusion Studio and HomeSite 5, along with support for the latest ColdFusion MX tags.

Note: This book shows how to create ColdFusion applications by writing your code manually. It does not address how to create ColdFusion pages by generating code with wizards. For information about using wizards to generate CFML code, see the product documentation for Dreamweaver MX and HomeSite+.


Creating a ColdFusion page

Creating a ColdFusion page involves using tags and functions. The best way to understand this process is to create a ColdFusion page.

In the following procedure, you will create a simple ColdFusion page by using HTML tags, one ColdFusion tag, and two ColdFusion functions. The following table briefly explains the ColdFusion tags and functions:

Element | Description
Now() | A function supported in CFML that you can use to retrieve information from your system. You will use the Now() function in the following procedure to return the current date that is retrieved from your system.
DateFormat() | A function that instructs ColdFusion to format the date returned by the Now() function.
cfoutput | A ColdFusion tag that you use to return dynamic data (data retrieved from a database) to a web page. You will use the cfoutput tag in the following procedure to display the current date retrieved from your system.

Note: ColdFusion tags and functions are considered primary elements of CFML. You will learn more about these elements and others later in this book.

To create a ColdFusion page:

  1. Open your editor and create a blank file.
  2. Enter the following code on the page:
    3. <html>
<head>
<title>A ColdFusion Page</title>
</head>
<body>
<strong>Hello world, this is a ColdFusion page.</strong>
<br>
<cfoutput> Today’s date is #DateFormat(Now())# </cfoutput>
</body>
</html>


Saving your ColdFusion page

In order for the ColdFusion server to process the page, you must save the ColdFusion page on a computer where the ColdFusion server is installed. If you are creating your pages on a local server (on which ColdFusion is running), then you can save the pages locally; if you are using a remote server, then you must save your pages on that server.

To publish ColdFusion pages on the Internet, you must save the pages under the web-root directory.

To save the code you just typed (to create a ColdFusion page):

  1. Create a new directory called test under the web_root directory.
  2. In the test directory, save the file as cfpage.cfm.


Browsing your code

To ensure that the code you wrote is working as expected, you must view the ColdFusion page in a browser. The following procedure describes how to view the ColdFusion page that you created earlier.

To view the ColdFusion page:

  1. Open a web browser and go to the following URL:

    2. http://127.0.0.1/test/cfpage.cfm

    The address 127.0.0.1 refers to the localhost and is only valid when you view pages locally. The URL for a remote site would include the IP address of the server where ColdFusion is installed; for example: http://<serveripaddress>/test/cfpage.cfm.

    The following figure shows the cfpage.cfm in the browser

    This is a picture of the feature being described.

  2. Do the following tasks:
    1. View the source code that was returned to the browser. In most browsers, you can view the source by right-clicking on page then selecting View Source.
    2. Compare the browser source code with the source code that appears in your editor. Notice that the CFML tags were processed on the page but did not appear in the source that was returned to your browser.

      3. As described in Chapter 1, ColdFusion processes all the instructions (CFML tags and functions) it receives on a page, and then returns the results of the instructions that your browser can interpret and display.


Understanding CFML elements

CFML consists of two primary language elements: tags and functions. Tags let you perform operations such as accessing a database. Functions can return data and do other operations like retrieving the system date. Almost everything you want to accomplish with ColdFusion will involve using tags and functions.

You will use another important element known as a variable. Variables are an important part of most programming languages and are equally important with CFML. Variables let you store information in memory and enable you to pass data.

The following sections describe how to use these three elements.


Tags

You can think of tags as commands that you use to instruct the ColdFusion server to perform operations. These operations might include selecting data from a database, reading a file that resides on the server, or showing the results of processing.


Tag syntax

As discussed in Chapter 1, ColdFusion tags are similar to HTML tags. ColdFusion tags are enclosed in angle brackets and often have a start and end tag. The start tag encloses the tag name in brackets, like this:

<tagname>

Most often the end tag encloses the tag name in brackets and includes a slash (/), like this:

</tagname>

The information processed by ColdFusion is placed between the start and end tag, like this:

<tagname>
info to be processed ...
</tagname>

ColdFusion tags, for the most part, share these common characteristics:

  • All start with cf.
  • A start and end tag.
  • Use of attributes (like html tags), and most attributes have values.

Some ColdFusion tags, such as cfset, omit the closing tag. This type of tag uses one set of angle brackets and places all the required information between the left (<) and right (>) angle brackets, like this:

<cfset name="bob">

For a complete list of tags and their syntax, see CFML Reference.


Tag attributes

Tag attributes instruct the ColdFusion server about the details of an operation. For example, to update a database table, the server needs to know specifics about the database, such as the database name and the table name. The code required to write this type of statement might look like this:

<cfupdate datasource="mydb" tablename="mytable">

where datasource and tablename are attributes of the cfupdate tag and "mydb" and "mytable" are attribute values.

For a complete list of tags and their attributes, see CFML Reference.


Functions

Typically, a function acts on data. It can generate a value or a set of values, usually from some input. You can perform the following operations (actions) with functions:

  • Manipulate data and time values
  • Examine a value or variable
  • Display and format information
  • Manipulate string data
  • Retrieve system information and resources
  • Perform mathematical operations


Using functions on values

Usually, a function performs an operation on a value, and the value can include the value of a variable. For example: to format the value of a variable containing a value in dollars, the code to write this statement might look like this:

#DollarFormat(price)#

The DollarFormat function returns a value as a string and formats that value with two decimal places, thousand separator, and dollar sign. The pounds signs (#) around the function instruct ColdFusion to evaluate the content between the pound signs and display the value.


Functions and parentheses

All functions have parentheses, regardless of whether the function acts on data. Consider the following function:

#Now()#

If you put anything inside the parentheses of the Now() function, an error would occur. The Now() function returns an unformatted date and time. However, you can format the results of this function with other functions, such as the DateFormat() or TimeFormat() functions.


Nesting functions

Functions can generate data as well as act on data. Consider the following example:

#DateFormat(Now(), "mm/dd/yyyy")#

In this example, the Now() function generates the date, and then the DateFormat function formats the date.


Functions and pound signs

You use pound signs (#) with functions to display the results of a function on the page. Pound signs tell the ColdFusion server to evaluate the content between the pound signs and display the value, for example:

<cfoutput>
Hello world, <br>
Today’s date is #DateFormat(Now(), "mm/dd/yyyy")#
</cfoutput>

The following figure shows the output of this example:

This is a picture of the feature being described.

If you did not include the pound signs around the DateFormat(Now(), "mm/ddyyy") function, the output for the previous example would display as follows:

This is a picture of the feature being described.

For more information about how to use pound signs with functions, see Developing ColdFusion MX Applications with CFML.


Variables

Variables let you store data in memory on the server. Variables always have a name and a value. You can assign a value to a variable, or you can instruct ColdFusion to assign variable values based on data that it retrieves from a data source, such as a database table.


Naming variables

You must use the following rules for naming ColdFusion variables:

  • Names are case insensitive (uppercase, lowercase, or mixed case).
  • Names can contain only letters, numbers, and underscore characters.
  • Each name must begin with a letter.
  • Special characters (such as double quotation marks ("), reserved names (such as functions and tags), and spaces are not allowed.


Ways to use variables

You can use a variable for the following purposes:

  • Store data collected from a form.
  • Store results of a calculation (such as the number of database records returned).
  • Use as input to a function.


Creating variables with the cfset tag

ColdFusion lets you create variables as you need them. You create the variable (name and value) using the cfset tag. The syntax for this tag is:

<cfset variable_name = value>

In the following examples, the variables are assigned a string literal value. All string literal values are surrounded by double quotation marks.

<cfset my_first_name = "Kaleigh">
<cfset my_last_name = "Smith">

In the next example, ColdFusion uses the values of the my_first_name and my_last_name variables to set the value for the my_full_name variable in the last line of code. The ampersand (&) string operator joins the variables, and the space surrounded by double quotation marks (" ") adds a space between the variables.

<cfset my_first_name = "Kaleigh">
<cfset my_last_name = "Smith">
<cfset my_full_name = variables.my_first_name & " " & variables.my_last_name>

Tip: String values assigned to a variable must be enclosed in single (’) or double (") quotation marks. Numeric or Boolean values assigned to a variable do not require single or double quotation marks.

So far all the variable examples shown have been about local variables. Local variables are variables that you can use only on the current ColdFusion page. As shown in the previous example, a Variables prefix was used to reference an existing variable on the page. Using a prefix when referencing a variable is important because ColdFusion supports many types of variables. The syntax for referencing a local variable is as follows:

variables.variablename

Because ColdFusion lets you use the same name with variables of more than one type, ColdFusion relies on scope referencing. In scope referencing, you preface the variable’s name with the scope when you refer to that variable.


Other variables and their scope

ColdFusion supports many types of variables. Each type has it own scope, or where it can be referenced, and its own way of referencing that variable type. The following table identifies some of the more common types of variables and their prefixes:

Scope | Prefix | Description
variables (local variable) | Variables | Variables created using cfset or cfparam. Most often you define the variable on the current page or on a page that you include using cfinclude.
Form | Form | Data entered in tags in an HTML form or ColdFusion form and processed on the action page.
URL | URL | Variables passed to a page as URL string parameters.
Query | QueryName | Variables that are named based on the column names that you select in the database table. The values are created when you execute the query that selects data from the database.

You will use these other types of variables in Part II of this book. For additional information about variables, see CFML Reference.


Displaying variable output

Output is what remains after the ColdFusion server processes the CFML tags on a page. Usually the output has two parts:

  • Information that the user sees (for example, a confirmation message)
  • Information that is stored by the server as a result of processing (for example, user input collected from a form)

One of the tags that ColdFusion provides to display output is the cfoutput tag. The cfoutput tag instructs ColdFusion to process all the code between the cfoutput start and end tags. The syntax for the cfoutput tag looks like this:

<cfouput>
{normal html, text, and coldfusion processing instructions}
</cfoutput>

To return the value of a variable, you must always surround the variable name with pound signs (#) and place the variable name between the cfoutput start and end tags. For example, the following code creates a variable and instructs the ColdFusion server to return the value of the variable.

<cfset my_first_name = "Kaleigh">
<cfset my_last_name = "Smith">
<cfset my_full_name = variables.my_first_name & " " & variables.my_last_name>
<cfoutput>
#variables.my_full_name#
</cfoutput>

The following is the output:

Kaleigh Smith


Working with CFML expressions

Expressions are an important part of the ColdFusion language. Expressions are a collection of different elements, ColdFusion variables, functions, and operators. You can think of them as strings of text that consist of one or more of the following elements:

  • Literal text (string), numbers, dates, and other values
  • Variables
  • Functions
  • Operators (& for joining statements, + for addition, and so on)

Many examples of expressions were shown in this chapter; for example:

  • #variables.my_full_name#
  • DateFormat(Now())
  • my_first_name= "Kaleigh"

When you build expressions in ColdFusion, you can include simple and complex elements; how you represent these elements determines how ColdFusion processes your program.


Building expressions

In ColdFusion, you build expressions as you need them. The expressions can include simple elements, such as the expressions shown previously, or they can include complex elements, such as arithmetic functions, strings, and decision operators. (You build some complex expressions in Part II of this book.)

As mentioned, it is important that elements are identified properly in your expression so ColdFusion processes them as expected, and you can avoid unnecessary errors. When writing expressions, consider the following coding practices:

  • Character case consistency
  • When to use the pound (#) sign
  • When quotation marks are needed


Specifying a consistent character case

Because the ColdFusion server is case-insensitive, you can write expressions using all uppercase, all lowercase, or mixed case. However, for code readability and consistency, you should use the same character case in all your programs. If you write your programs using the same case rules, you might prevent errors from occurring when you combine CFML on a page with case-sensitive languages, such as JavaScript.


Specifying pound signs to denote functions or variables

In ColdFusion, you specify pounds signs to denote functions and variables within a string of text. You use pounds signs to show the results of the function or variable on the page. Pounds signs instruct the ColdFusion server to evaluate the function (or variable) between the pound signs and display the value. The value of the function (or variable) appears in the browser as a result.

The following list identifies some common ways to use pound signs:

  • In the following example, you include the pound signs to return the value to a page:
    • <cfoutput> Hello #variables.my_first_name# </cfoutput>

If you omit the pound signs, the text, not the value, appears on the page.
  • In the following example, you do not include the pound signs because you are using cfset to assign one variable’s value to another value:
    • <cfset my_full_name = variables.my_first_name & " " & variables.my_last_name>
  • To display a pound sign on a page, you must designate the pound sign as a literal character. You do this by using two pound signs (##); for example:
    • <cfoutput>
##1: Your name.
</cfoutput>

The result is the following output:

#1. Your name.

For more information and examples on using pound signs in expressions, see Developing ColdFusion MX Applications with CFML.


Specifying quotation marks around values

When assigning literal values to variables, you must surround the literal value with double quotation marks or single quotation marks. ColdFusion interprets the content between the quotation marks as a literal value and assigns that value to the variable; for example:

<cfset my_first_name = "Kaleigh">
<cfset my_last_name = "Smith">
<cfset my_age = 5>

ColdFusion instantiates the variable my_first_name to the string literal Kaleigh. Further, Smith is assigned to the variable my_last_name and 5 is assigned to age.

When referencing a variable by its name, you do not surround the name with quotation marks; for example:

<cfset the_string = "My name is " & variables.my_first_name &
" and my age is " & variables.my_age>

My name is is literal text and, you therefore, surround it with quotation marks. The variable references variables.my_first_name and variables.my_age are not surrounded by quotation marks. ColdFusion uses the values of the referenced variables (Kaleigh and 5, respectively) when assigning the value to the variable the_string.

To display quotation marks on a page as literal characters, you must double the quotation marks; for example:

<cfset mystring = "We all shouted ""Happy Birthday"" when he entered the room.">
<cfoutput>
#mystring#
</cfoutput>

The result is the following output:

We all shouted "Happy Birthday" when he entered the room.


Specifying operators in expressions

In ColdFusion, you use operators to test conditions; for example, you use the IS operator to test for equality. When using operators in expressions, you must only use supported logical operators that ColdFusion can interpret properly. For example, if you use the greater than operator (>)or the less than operator (<), ColdFusion interprets these operators as the start or end of a tag.

The following table lists the nonsupported logical operators and their equivalent ColdFusion operators:

Nonsupported logical operator | Equivalent ColdFusion decision operator | Description
= | IS, EQUAL, EQ | Tests for equality.
< | LT, LESS THAN | Tests for less than.
<= | LTE, LE, LESS THAN OR EQUAL TO | Tests for less than or equal to.
> | GT GREATER THAN | Tests for greater than.
>= | GTE, GREATER THAN OR EQUAL TO | Tests for greater than or equal to
< > | IS NOT, NEQ, NOT EQUAL | Tests for nonequality.
 | CONTAINS | Tests whether a value is contained within a second value.
 | DOES NOT CONTAIN | Tests whether a value is not contained within a second value.


Arithmetic operators

The following table lists the arithmetic operators that ColdFusion supports:

Operators | Description
+, -, *, / | The basic arithmetic operators: addition, subtraction, multiplication, and division. In the case of division, the right operand cannot be zero.
+, - | Unary arithmetic operators for setting the sign of a number either positive or negative (+ or -).
Mod | Returns the remainder (modulus) after a number is divided by a divisor. The result has the same sign as the divisor. The right operand cannot be zero; for example: 11 MOD 4 is 3.
\ | Divides two integer values. Use the \ (trailing slash) to separate the integers. The right operand cannot be zero; for example: 9 \ 4 is 2.
^ | Returns the result of a number raised to a power (exponent). Use the ^ (caret) to separate the number from the power. The left operand cannot be zero; for example: 2 ^ 3 is 8.


String operator

The following table describes the one ColdFusion string operator that is a concatenation operator:

Operator | Description
& | Concatenates strings.


Understanding conditional processing

To this point, all the coding examples shown are considered linear coding examples. Linear code is when ColdFusion executes code starting with the first line on the page, and processes every line in order. Although you will use linear code in your applications, you will often write code that performs various actions based on conditions, such as the following:

  • Determine if a user entered a value in a form field.
  • Display results based on user input.
  • Display messages based on the time of day.

You use conditional processing to customize the behavior of your application. Conditional processing facilitates decision making and lets you control how the code on a page is processed.

In ColdFusion, you implement conditional processing with flow control tags. These tags are similar to other programming language control elements, such as if, then, and else.


Conditional processing tags

ColdFusion provides several tags that let you control how a page is processed. When using these tags, you can facilitate decision making in your code. The most fundamental tags used to control code execution are the cfif, cfelse, and cfelseif tags. Because you will see and use these tags in Part II of this book, the following sections provide a basic introduction on how to use these tags. For more information about other conditional processing tags, including tags for looping, see Developing ColdFusion MX Applications with CFML.


Using cfif to evaluate true or false conditions

To create statements that let you evaluate conditions and perform an action based on the result, you use the cfif tag to create a cfif statement. The basic syntax for a cfif statement is as follows:

<cfif expression>
HTML and CFML tags executed if expression is True.
</cfif>

In the previous example, ColdFusion only executes the code inside the cfif statement if the expression evaluates to true. To perform actions if the expression is false, you can use the cfelse tag. For example, if the following cfif expression evaluates to false, then the code between the cfelse tag and the cfif tag is processed:

<cfif expression>
   HTML and CFML tags executed if expression is True.
<cfelse>
   HTML and CFML tags executed if expression is False.
</cfif>


Using cfelseif to evaluate multiple expressions

To evaluate multiple expressions in a cfif statement, you can use cfelseif and cfelse in your statement, for example:

<cfif expression 1>
   HTML and CFML tags executed if expression 1 is True.
<cfelseif expression 2>
   HTML and CFML tags executed if expression 2 is True.
<cfelse>
   HTML and CFML tags executed for expression(s) that is False.
</cfif>

The following example shows you how you can evaluate multiple expressions using these tags. In this example, you created a form in which users can enter their state to determine their state tax:

<cfoutput>
<cfif form.state IS "MA">
   #form.state# State Tax: 8.5%
<cfelseif form.state IS "VA">
   #form.state# State Tax: 8.2%
<cfelse>
   #form.state# State Tax Unknown
</cfif>
</cfoutput>

The output of this cfif statement is based on the value entered by the user. If the user enters MA in the state form field, the state tax results returned is 8.5%. If the user enters VA in the state form field, the state tax results returned is 8.2%. If the user enters any other state in the state form field, State Tax Unknown is returned.


Processing form data

Virtually all web applications that gather and write information to a database use a form to accomplish that task. Forms let you collect information from a user (using an order form, registration form, and so on) and write that information to a database. Like HTML, there are two independent steps for creating a form in ColdFusion:

  1. Creating the layout for the form itself.
  2. Writing the code to process the submitted information.


Form processing

Every form that you create in ColdFusion consist of two parts: the form page and the action page.These two pages work together to process user input. The form page contains the user interface elements, such as input fields, and radio buttons. The action page handles the processing of the form page data.

When a user submits a form, the form values are stored in form variables and sent to the action page for processing. The following figure shows the relationship between the form page and action page:

This is a picture of the feature being described.

In order for the form page to find its corresponding action page, the action statement in the form tag must be correct. The form tag includes the information that tells the server where to send the data that it collects. It also tells the server how to send it. To processes these instructions to the server, the form tag uses the following syntax:

<form action="actionpagename.cfm" method="Post">
   HTML and CFML form tags
</form>

The first attribute (action) in the form tag lets you specify where to send the data. The page that you specify where to send the data is the name of the action page. The second attribute in the form tag is method. The only method that ColdFusion supports is post. All ColdFusion forms must set the method attribute to post.

In Part II of this book, you will use ColdFusion form tags to create forms and write collected values to a database.


Commenting your code

As in other programming languages, it is important to include comments in the code. You should comment your code for the following reasons:

  • Commented code is easier to debug than code that is not commented.
  • If you describe the code on the page, it is easier to make modifications.
  • Commented code tends to be better organized.


Comment tag

The ColdFusion comment tag is similar to the HTML comment tag, except that it has three dashes instead of two:

<!--- This is a CFML comment --- >

ColdFusion comments are not returned to the browser because the ColdFusion server processes and omits the comments from the page. The user will never be able to read your comments.

Previous


Database Fundamentals

This chapter provides a quick overview of relational database concepts and terms. It describes what a database is and how it is organized. It also discusses the Structured Query Language (SQL) that you use to interact with databases.

Contents
  • Understanding database basics
  • About SQL
  • Using SQL with ColdFusion
Next


Understanding database basics

Even though you do not need a thorough understanding of database management systems to create ColdFusion applications, you must understand some basic concepts and techniques about databases. The information in this chapter will get you started with ColdFusion.


What is a relational database?

A relational database is a structured collection of information that is related to a particular subject or purpose, such as an inventory database or a human resources database. You use databases to manage information. Information, such as product name, cost, and on-hand inventory, is stored in a database. Within the database, you organize the data into storage containers called tables. Tables are made up of columns and rows. Columns represent individual fields in a table. Rows represent records of data in a table. You can think of database tables as grids, as in the following example:

This is a picture of the feature being described.

Each field in the table contains one piece of information. In an employee table, for example, one column contains the employee name, another contains the employee phone number, and the address, city, state, zip, and salary are all stored in their own columns. Each record represents one set of related information. For example, an employee table might store information about one employee per row. The number of rows in a table represents the total number of table records.


Understanding Relational Tables

In a database, you can organize data in multiple tables. For example, if you manage a database for the Human Resource department, you might have one table that lists all the employees information and another table that lists all the departments.

This is a picture of the feature being described.

Because you have multiple departments for employees, but you would not store the information about the departments in every employee row for several reasons:

  • The department information is the same for each employee in a given department, however, repeating the department information for each employee is redundant. Storing redundant data takes up more disk space.
  • If the department information changes, you can update one occurrence. All references to that department are updated automatically.

Storing multiple occurrences of the same data is rarely a good thing. Good relational database design separates application entities into their own tables. Key values from one table are often stored in a related table rather than repeating the information. The key value is used to join the data between the tables to return the complete set of data required.


About SQL

SQL Structured Query Language) is a language that lets you communicate with databases. For example, you can use SQL to retrieve data from a database, add data to a database, delete or update records in a database, change columns in multiple rows, add columns to tables, and add and delete tables.


Using SQL to interact with a database

Unlike other computer languages, SQL is made up of a small number of language elements that let you interact efficiently with a database. Some of the more frequently used elements include these SQL commands:

Command | Description
SELECT | Use to retrieve (query) information in a database.
INSERT | Use to add records to a database.
UPDATE | Use to update information in a database.
DELETE | Use to delete information in a database.

In Part II of this book, you will be introduced to the syntax of these commands when you use them to build a ColdFusion application that interacts with a database. For additional information about SQL, consult any SQL primer.


Using SQL with ColdFusion

ColdFusion communicates with your data source through a database interface called JDBC. JDBC is a standard application programming interface (API) for accessing information from different database systems and different storage formats.


About data sources

A data source is a complete database configuration that uses a JDBC driver to communicate with a specific database. In ColdFusion, you must configure a data source for each database file that you want to use. After you configure a data source, the ColdFusion server is then capable of communicating with that data source through the JDBC driver.

You configure data sources in ColdFusion by using the ColdFusion administrator. Configuring Your Development Environment discusses how to configure the sample data source file that is supplied for use with Part II of this book. For more information about configuring a data source in ColdFusion, see Installing ColdFusion MX or Developing ColdFusion MX Applications with CFML.


Writing SQL and CFML statements to interact with a data source

After ColdFusion makes a connection to the data source, you can interact with that database by using SQL and ColdFusion.

To interact with an established data source, you need to include SQL statements in your CFML statements; for example:

<cfquery name="queryname" datasource="namedbfile">
   SELECT FirstName, LastName, DepartmentID
   From Employee
</cfquery>

In the previous example, the first attribute of cfquery is the name of the query. The second attribute of cfquery defines the name of the data source. The SELECT statement defines the fields (columns) to be retrieved from a tabled named Employee.


CFML tags that interact with a database

The following table lists the CFML tags you can use to interact with a database:

Command
Description
cfquery
To retrieve (query) information in a database.
cfinsert
To add records to a database.
cfupdate
To update information in a database.

In Part II of this book, you will be introduced to these tags when you use them to interact with the sample database. For more information about interacting with a database, see Developing ColdFusion MX Applications with CFML or CFML Reference.

Previous


Configuring Your Development Environment

This chapter describes how to set up your development environment for the tutorial. It specifies the tutorial file structure, and how to configure the database connection and debugging options in the ColdFusion Administrator. Additionally, it provides a brief overview of using Macromedia Dreamweaver MX or Macromedia HomeSite+ for ColdFusion development.

Contents
  • Verifying the tutorial file structure
  • Configuring database connection and debugging options
  • Macromedia development environment tools
Next


Verifying the tutorial file structure

Before you being the tutorial, verify that the configuration of the computer where ColdFusion is installed matches the file structure described in the following sections.

The files required to complete the Compass Travel tutorial (in Part II of this book) are installed under the web server root directory. The location of this directory varies, depending on whether you chose to configure a local third-party web server (such as IIS) or the ColdFusion stand-alone web server during installation, as follows:

  • For local third-party web server configurations, the files are installed in: webroot\cfdocs\getting_started.
  • For stand-alone ColdFusion web server configurations, the files are installed in: cfusionmx\webroot\cfdocs\getting_started.

The following figure shows the getting_started directory structure:

This is a picture of the feature being described.

ColdFusion MX installs two copies of the sample CompassTravel database file. The working copy is located in the db directory; a backup copy of the file is in the new_user_database directory.

To ensure that you are working with the original database file, verify that the file in the db directory has the same date as the backup file in the new_user_database directory. If the date of the file in the db directory is later than the backup file, replace the file in the db directory with a copy of the backup database.

Caution:Do not write to the database file in the new_user_ database directory. The backup file lets multiple users perform the tutorial in Part II of this book.

In each of the database subdirectories, the tutorial provides one sample database file for Microsoft Windows® users and one sample database file for UNIX® users. Windows users use a Microsoft Access file, and UNIX users use a PointBase file.

Note: The sample PointBase file consists of two files: compasstravel.dbn and compasstavel$1.wal. ColdFusion MX uses both of these files to work with the content in the the sample PointBase database.

Save all the files that you create for the tutorial application (in Part II of this book) in the my_app directory. This directory contains one subdirectory for images. The image subdirectory contains the required image files for the tutorial application.

The photos directory contains the required photo files for the tutorial application. The solutions directory provides sample application files that you can use when building the tutorial application.


Configuring database connection and debugging options

Prior to ColdFusion development, use the ColdFusion MX Administrator to define the connection to the sample database file and any optional debugging options.

To access the ColdFusion Administrator, do either of the following:

  • Select Start > Programs > Macromedia ColdFusion MX > ColdFusion MX Administrator.
  • Open a browser and go to one of the following URLs:
    • External web server users: http://localhost/CFIDE/administrator
    • Stand-alone web server users: http://localhost:8500/CFIDE/administrator

Note: If you are acessing the ColdFusion Administrator from a remote client, you must replace localhost with the IP address of the computer where ColdFusion MX is installed.

The following sections describe how to establish a connection to the sample tutorial database file and how to enable optional debugging settings.


Configuring the connection to the sample database file

The following procedures describe how to configure a connection to the sample database file (CompassTravel) using the ColdFusion Administrator. Prior to using Part II of this book to build the sample application, you must configure the Compass Travel database connection.

Perform one of the following procedures. The Microsoft Access procedure is for Windows users. The PointBase procedure is for UNIX users.

To define the connection to the sample Microsoft Access database:

  1. In the ColdFusion Administrator, select Data & Services > Data Sources.
  2. In the Add New Data Source dialog box, specify the following:

    Field
    Action
    Data Source name text box
    Specify the name CompassTravel.
    Note: Ensure that the name of the data source file does not contain any spaces. If the name contains a space, the data source connection fails.
    Driver drop-down list box
    Select Microsoft Access [Macromedia] .

  3. Click Add to configure the data source name and driver.

    4. The Macromedia Microsoft Access Data Source dialog box appears.

  4. Specify the following:

    Field
    Action
    Database File text box
    Specify the location of the CompassTravel.mdb file. Click Browse to locate and select the CompassTravel.mdb file.
    By default, ColdFusion MX installs the CompassTravel.mdb file in one of the following locations:
    • For third-party web server configurations: web_root\cfdocs\getting_started\db
    For standalone ColdFusion web server configurations: cfusionmx\web_root\getting_started\db
    Description text box
    Enter the following:
    Database file for Compass Travel tutorial

  5. Click Show Advanced Settings and ensure that the settings for CLOB and BLOB are enabled (checked).
  6. Click Submit to complete the data source configuration.

    7. The name CompassTravel appears in the Connected Data Sources dialog box.

  7. Click Verify All Connections to ensure that ColdFusion can access this file.

    8. OK appears in the Status column for successful connections.

    If the connection to the compass travel data source fails, do the following:

  8. Verify that the name of the data source file does not contain a space. If it does contain a space, delete the data source from the Connected Data Source dialog box. To do this, click the Delete action button associated with the CompassTravel data source name, then repeat the steps in this procedure to reconfigure this data source.
  9. Verify that the path specified for the Compass Travel database file is correct.

To define the sample PointBase database file:

  1. In the ColdFusion Administrator, select Data & Services > Data Sources.

    2. The Add New Data Source dialog box appears.

  2. Specify the following:

    Field
    Action
    Data Source name text box
    Specify the name CompassTravel.
    Note: Ensure that the name of the datasource file does not contain any spaces. If the name contains a space the data source connection fails.
    Driver drop-down selection box
    Select Other.

  3. Click Add to configure the data source name and driver.

    4. The PointBase data source dialog box appears:

    This is a picture of the feature being described.

  4. Specify the following:

    Field
    Action
    JDBC URL
    Enter the following JDBC URL for the Compass Travel pointbase files:
    jdbc:pointbase:compasstravel,database.home=/<home location>/wwwroot/cfdocs/getting_started/db
    The following is the default home location for stand-alone ColdFusion web server configurations:
    /opt/coldfusionmx/wwwroot/cfdocs/getting_started/db
    Driver Class
    Enter the following driver class:
    com.pointbase.jdbc.jdbcUniversalDriver
    Driver Name
    Specify Pointbase.
    Username
    Specify PBPUBLIC.
    Password
    Specify PBPUBLIC.
    Description
    Enter the following:
    Database file for Compass Travel tutorial

  5. Click Show Advanced Settings to ensure that the settings for CLOB and BLOB are enabled (checked).
  6. Click Submit to complete the data source configuration.

    7. The name CompassTravel appears in the Connected Data Sources dialog box.

  7. Click Verify All Connections to ensure that ColdFusion can access this file.

    8. OK appears in the Status column for successful connections.

    If the connection to the compass travel data source fails, do the following:

  8. Verify that the name of the data source file does not contain a space. If it does contain a space, delete the data source from the Connected Data Source dialog box. To do this, click the Delete action button associated with the CompassTravel data source name, then repeat the steps in this procedure to reconfigure this data source.
  9. Verify that the JDBC URL specified for the Compass Travel pontbase files is correct.


Enabling debugging options

The ColdFusion MX Administrator provides a variety of debugging settings that let you enable debugging information on a server-wide basis. If you are working on a development system, you can have these options turned on all the time. However, if you are working on a production system, you most likely will not want to have these options turned on, because the debugging information can appear on the bottom of an application page or in a dockable tree in your browser.

The following figure shows an example of how debugging information can appear when appended to the bottom of a page in a browser:

This is a picture of the feature being described.

The location of the debugging information or the type of debugging data shown varies, depending on the options that you enable on the Debugging page in the ColdFusion Administrator. In the following example, the debugging output includes general information about the ColdFusion server, the execution time of the application, and variable information.

This is a picture of the feature being described.

If you are using a development server to build the sample application in Part II of this book, you can enable some of these settings to help debug any unexpected problems.

Use the following steps to enable debugging options in the ColdFusion Administrator.

To enable debugging options:

  1. In the ColdFusion Administrator, select Debugging and Logging > Debugging.

    2. A list of debugging options appear on the Debugging Settings page.

  2. Select the Enable Debugging check box.

    3. When you select this option, the debugging service is enabled for all options already selected on the page.

  3. On Debugging Settings page, view the description of each option that is enabled. If you do not want to append debugging information for a specific option, clear the check box.

    4. For the purpose of the tutorial in Part II of this book, enable the following debugging options:

    Option | Description
Database Activity | Identifies database activity related to SQL query events.
Exception Information | Identifies ColdFusion exceptions raised in the debugging output.
Tracing Information | Lets you trace event information reported in the debugging output.
Form, URL and Session Variables | Displays variable information in the debugging output.

  4. Click Submit Changes when you are done.


Sending debugging information to remote clients

If you are using a remote client to perform the tutorial in Part II of this book, you must specify your IP address to receive debugging information. If you are working on a local client (the computer where ColdFusion is installed), this procedure is not necessary.

To recieve debugging information when using a remote client:

  1. In the ColdFusion Administrator, select Debugging and Logging > Debugging IP Addresses.

    2. The Debugging IP Address page appears.

  2. In the IP Address text box, enter the IP address of your remote client.
  3. Click Add.


Macromedia development environment tools

Macromedia Dreamweaver MX is the preferred development environment for building ColdFusion MX applications. It combines the best code editing features of ColdFusion Studio with the visual design features of Dreamweaver.

This is a picture of the feature being described.

Dreamweaver MX supports the latest ColdFusion MX features and tags. It also includes Macromedia HomeSite+, which combines all the features of ColdFusion Studio and HomeSite 5, along with support for the latest ColdFusion MX tags.

With Dreamweaver MX or HomeSite+, you can author and test your application code from a local or remote client. Both of these tools let you save your code directly to the server computer where ColdFusion is installed. The following sections provide an overview of Dreamweaver MX, and information on how to configure Dreamweaver MX and HomeSite+ for ColdFusion development.


The Dreamweaver MX environment

As a ColdFusion developer, you can build ColdFusion MX applications by writing the code manually or generating the code by using one of the code-generating tools provided with Dreamweaver MX.

This is a picture of the feature being described.


Features for ColdFusion developers

Dreamweaver MX provides a wide variety of code editing features for ColdFusion developers, including the following:

  • Rich tag editors for quickly setting attributes and values for every CFML tag.
  • Code hints for writing CFML tag attributes.
  • Code validator for validating code readiness against other ColdFusion versions.
  • Tag chooser with integrated reference material for inserting ColdFusion tags.
  • Snippets panel for reusing code.
  • Integrated debugging display for quickly pinpointing problem areas in the code.
  • Remote ColdFusion server connection for browsing remote data sources and files.

If you plan to use Dreamweaver MX or HomeSite+ to build the sample ColdFusion application in Part II of this book, see the following sections for information about configuring these tools for ColdFusion development.


Configuring Dreamweaver MX for ColdFusion development

Before you use Dreamweaver MX to create the sample application in Part II of this book, you must configure Dreamweaver to recognize the tutorial files and data sources.

To configure Dreamweaver MX to create the sample application:

  1. Create a site that contains the tutorial files.

    2. For information about how to create a site in Dreamweaver MX, see the Dreamweaver MX online Help or Using Dreamweaver MX.

  2. Specify ColdFusion as the application server document type.

    3. For information about how to specify ColdFusion as the server document type, see the Dreamweaver MX online Help or Using Dreamweaver MX.

  3. Specify ColdFusion MX as the site application server.

    4. For information about how to specify ColdFusion as your application server, see the Dreamweaver MX online Help or Using Dreamweaver MX.

    Tip: If you are a new Dreamweaver MX user, you can perform the Dreamweaver MX tutorial before using Dreamweaver MX to build the sample application. The tutorial in this book does not describe how to use Dreamweaver. The purpose of this tutorial is to teach you how to build ColdFusion applications using ColdFusion Markup Language (CFML).


Configuring HomeSite+ for ColdFusion development

Before you use Macromedia HomeSite+ to create the sample application in Part II of this book, you must configure HomeSite+ to recognize the tutorial files and data sources.

To use HomeSite+ to create the sample application:

  1. Establish a secure connection to the ColdFusion Server environment where the tutorial files are installed. Establishing a connection to the ColdFusion Server is a prerequisite for accessing the ColdFusion data sources.

    2. For information, see the online Help or product documentation for HomeSite+.

  2. Enable internal browsing to view and process the ColdFusion application files.

    3. For information, see the online Help or product documentation for HomeSite+.

  3. Determine how you want to work with the tutorial files. You can view and access the tutorial files using the Resource Area in the HomeSite + window. You can also set up a project to manage the files more efficiently.

    4. For more information, see the online Help or the product documentation for HomeSite+.

    Note: The tutorial provided in this book does not describe how to use HomeSite +. The purpose of this tutorial is to teach you how to build ColdFusion applications using ColdFusion Markup Language (CFML). For more information about HomeSite +, see the product documentation or online Help.

Previous


Application development steps

Most software applications perform three major functions:

  • A user interface to capture data.
  • Logic to validate the captured data.
  • A database to store the validated data.

The process steps to develop these major functions varies from project to project. In this tutorial you will review or participate in the following application development steps to build the Compass Travel Trips Maintenance application:

Step | Description
1 | Determine the application functional requirements.
2 | Determine the data requirements by identifying the information required for the Trip Maintenance application.
3 | Design the database for your application by exploring the database tables that will store the trip information.
4 | Develop the ColdFusion application pages.

An overview of each of these application development steps is explored in greater detail in the following sections.


Determining the application functional requirements

Before you can build the sample application, you must understand the functional requirements underpinning its design. The design of the sample application centers around the daily tasks performed by Compass Travel’s trip coordinators. These tasks are listed in the following table:

Trip coordinator task | Description
Produce current trip listing | To help Compass Travel agents take trip reservations over the phone and in person, the trip coordinator maintains a list of current trip offerings.
Provide trip information | On an ad hoc basis, Compass Travel management asks the trip coordinator to develop lists of trips that meet specific criteria.
Maintain trip information | The trip coordinator is responsible for keeping all trip information up to date. To do this, the coordinator needs to locate a trip to edit it or delete it. Additionally, the coordinator must be able to add a new trip.
Ensure the quality of trip information | The trip coordinator is responsible for periodically browsing the current trip offerings to ensure that all the information is accurate. Additionally, when adding a new trip or editing an existing one, the trip coordinator must ensure that the data adheres to the Compass Travel business rules.

You can derive several functional requirements for the new application from the preceding table. For example, the sample application must provide the following functions:

Functional requirement
1 | The ability to generate trip listings
2 | A trip query facility based on user supplied criteria
3 | Trip browsing functionality
4 | The ability to add a new trip
5 | The ability to delete an existing trip
6 | The ability to edit an existing trip
7 | A mechanism to validate new or updated trips against Compass business rules

In the lessons that follow, you will build ColdFusion pages to address each of these functional requirements. Central to every requirement is the notion of a trip. Before you can build code to address any of these requirements, you must understand which attributes of a trip are important to Compass Travel. For this you must determine the data requirements for the application. Understanding the data requirements is essential to building the proper database to hold the application data.


Determining the data requirements

Prior to creating the application pages to capture trip information, you must determine what type of data is required about each trip. For the example, in this tutorial, the Compass Travel Trip Coordinator must maintain the following information about each trip:

  • Trip name
  • Type of event (surfing, mountain climbing, kayaking, etc.)
  • Trip description
  • Trip location
  • An indicator of whether a deposit is required
  • Departure date
  • Return date
  • Total number of people who can attend the trip
  • Price
  • Base cost
  • Assigned trip leader
  • Trip photograph

By collecting the preceding information about each trip, the Compass Travel website can market its trips online to the general public. Customers booking a trip need to know the trip name, when the trip begins and ends, the price, and a description. Additionally, the trip coordinator must identify the file name for a photograph of each trip. The Compass Travel website displays the photograph to further entice prospective customers into booking the trip. Finally, Compass Travel considers it important to store the base cost for each trip to help determine trip profitability. The cost must be captured, but it is for Compass Travel internal use only. Cost is not shown on the public website.


Designing the database for your application

After you identify the information to collect, you must consider where to store the data. Prior to creating the data collection form and instructing ColdFusion where to store the form data, you must have a database ready to accept the data.

If you had to create the Compass Travel database, you would create a table named Trips to store the information that you plan to collect about each trip. The table would look something like this:

This is a picture of the feature being described.


Recognizing the data types

Each field in the Trips table has a data type attribute that describes the type of data that can be stored in the column. For instance, the tripName column can contain text data while the price column can only contain numeric data. It is important to know what type of data is valid for each column so that your data collection forms can validate against incorrect values entered by the user.

Looking closer, you might wonder why the eventType column is a number and not a text data type column. Recall that data requirements analysis identified the need for a type of event (surfing, mountain climbing, kayaking, and so on). The purpose of this column is to classify trips into various categories based on the trip activity. It is essential that the application classifies the trips consistently. Therefore, it is important to offer a list of event types for the user to select, rather than to accept free text input.

To present a list of event types for user selection, the event types are stored in a separate table, the Eventtypes table. This table is already populated and contains the following rows:

This is a picture of the feature being described.


Establishing a relationship between the two tables

When the user selects an event type from the list obtained from reading the eventtypes table, the correct event type must be saved to the trips table with all the other trip related data. The application could store the eventType (for example, mountain climbing) itself into the eventType column in the Trips table. But if the name Mountain Climbing were later shortened to Climbing in the eventtypes table, new mountain climbing trips would be classified differently than ones saved before the change. For this reason and to save space in the database, the key to the eventtypes row (eventTypeID) is stored in the trips table instead.

The two tables are said to have a relationship. This relationship works by matching data in key fields. In this case, the matching fields consist of a primary key (eventTypeID) from the Eventtypes table, which provides a unique identifier for each record, and a foreign key (eventType) in the Trips table. The foreign key contains the same value as the primary key, pointing to a unique event type. The following figure shows this relationship:

This is a picture of the feature being described.


Developing the sample application

Given the application functional requirements and the database provided, you are ready to use ColdFusion to develop the Trips Maintenance application. The remaining lessons in the tutorial will step you through the process of constructing this application. When you are done, the main page for the Trip Maintenance application will appear as follows:

This is a picture of the feature being described.

The main application page is where users will come to view information about trips and to navigate to other ColdFusion pages to add, edit or search for new trips.

The following lessons, explain how to do these tasks:

  • Develop a trip search facility (Lesson 2).
  • Build the main application page (Lesson 3).
  • Implement browsing and trip maintenance functions (Lesson 4).
  • Write code to enforce Compass Travel business rules (Lesson 5).
  • Develop the trip add and update pages (Lesson 6).


How to proceed

Each lesson in the tutorial is designed to let you proceed at your own pace. At any time, you can stop and later return to that place in a lesson so that you can complete all the sections in the lesson.

Each lesson guides you through a scenario to enhance the Compass Travel Trip Maintenance application. Sections within a lesson present basic programming concepts that you need to understand before completing the section exercise(s).

Depending on your programming experience, you can read the entire lesson then proceed to the hands-on exercises, or you can skip some information in the lesson and proceed directly to the exercises.


Working directories

The following table describes the working directories for this tutorial:

Directory | Description
my_app | You will save all your source code in this directory.
solutions | You can find solutions to all the exercises in this directory.
db | You will use this directory as the working directory for the Compass Travel database. Note: As discussed earlier in Chapter 4, you should verify that the Compass Travel database file residing in the db directory is the original file supplied. This file should have the same date as the file in the new_user_db directory. If date on the file in the db directory is different, replace the file in db directory with a copy of the Compass Travel database file that is located in the new_user_db directory.
photos | You will use this directory to access existing trip photographs.
images | You will use this directory to access application image files.


Locating the working directories

You can locate the working directories for this tutorial under your web root directory. For example, the directory path on your computer might be:

(on Windows NT) <mywebserverdocroot>\cfdocs\getting_started
(on UNIX) <mywebserverdocroot>/cfdocs/getting_started

You can view ColdFusion application pages on your local computer by opening a web browser and entering one of the following URL:

Configuration | URL
For local third-party web server configuration | http://localhost/cfdocs/getting_started/my_app/<pagename>.cfm
For standalone ColdFusion web server configuration | http://localhost:8500/cfdocs/getting_started/my_app/<pagename>.cfm

For more information about the tutorial file structure and the location of the getting_started subdirectories, see Verifying the tutorial file structure.


Requirements

To use this tutorial, you must have the following components installed:

  • ColdFusion Server For information on how to install ColdFusion Server, see Installing ColdFusion MX.
  • Database Management System A database management system can be installed on the same computer as the ColdFusion Server or on a separate computer. For the purpose of this tutorial, a Microsoft Access database file for MS Windows users and a PointBase database file for UNIX users has been provided. For information about how to configure the Compass Travel datasource, see Configuring Your Development Environment. For additional information about configuring a data source, see Installing ColdFusion MX.
  • Web browser You can use Internet Explorer (4.0 or later) or Netscape Navigator (6.0 or later).
  • Text editor or IDE (Interactive Development Environment) Macromedia recommends that you use Dreamweaver MX. However, you can use HomeSite+, ColdFusion Studio, any text editor, or IDE. In the exercises in this tutorial, the term editor means Dreamweaver MX, HomeSite+, ColdFusion Studio, or any text editor or IDE of your choice.

    • Note: The default file extension used for ColdFusion application pages is.cfm.

Previous


Writing Your First ColdFusion Application

In this lesson, you begin the construction of a ColdFusion web application for the fictitious company, Compass Travel. The exercises in this lesson guide you through the steps of creating queries and forms to search for and display trip offering information from the Compass Travel relational database.

This lesson explains how to do the following tasks:

  • Construct a query to retrieve information from a database.
  • Develop a search form to accept user criteria.
  • Use dynamic SQL to build a flexible search query.
  • Develop a results form to display the result of the search.
Next


ColdFusion tags and functions introduced in this lesson

The following table identifies the ColdFusion tags and functions that you use in this lesson to build your first ColdFusion application:

Element
Type
Description
PreserveSingleQuotes
Function
Enables you to use single quotation marks in variables used in SQL statements.
cfoutput
Tag
Instructs the server to show the results of variables, functions, or text that is specified between the cfoutput start and end tags.
cfquery
Tag
Submits SQL statements to a JDBC data source.
cfif
Tag
Creates conditional statements.
cfset
Tag
Defines a ColdFusion variable. If the variable already exists, cfset resets it to the specified value.


Creating your first ColdFusion application

As you recall from Creating a Main Application Page, two of the requirements for the Trip Maintenance application are the ability to generate trip listings and a trip query facility. You will create a search interface that meets both of these requirements in this lesson.

The following list identifies the components that you will create in this lesson:

  • Dynamic Trip List page The purpose of the Trip List page is to present an up-to-date lists of trips on the Compass Travel website.

    • This is a picture of the feature being described.

  • Trip Search form The purpose of the Trip search form is to enable Compass Travel employees to search and view brief details about existing trips on their website.

    • This is a picture of the feature being described.

  • Trip Search Results page The purpose of the Trip Search Results page is to display the results of a trip search.

    • This is a picture of the feature being described.

The primary users of these components are the Compass Travel coordinators and agents, not the general public.


Application development steps

You will review or participate in the following application construction steps:

Steps | Description
1 | Create a dynamic web page that displays a list of trips.
2 | Design the constraints for the search interface.
3 | Develop ColdFusion pages to capture user search criteria and display the results.


Using a web page to list trips

To help Compass Travel agents take trip reservations by telephone and in person, the trip coordinator maintains a list of current trip offerings. Years ago, the coordinator would type the list and fax it to the various Compass Travel offices in an effort to keep everyone informed. When Compass Travel built an intranet accessible by all offices, the trip coordinator added the following HTML web page to the site:

This is a picture of the feature being described.

Each time the Trip List HTML page is rendered in a browser, it displays the same web page. Since the page always shows an identical trip list, it is considered a static web page. You should only use static web pages when you are creating a page that is not likely to change often.


Converting to a dynamic web page

Using the static web page approach, the Trip Coordinator needs to modify all the web pages that reference trip lists when trips are added, deleted, or trip names are changed. This manual process of updating each web page can lead to inaccurate or untimely information. Luckily, since Compass Travel has built a database that contains a list of trips, you can build a more accurate and timely solution for the trip coordinator. To accomplish this, you must understand how to issue a SQL SELECT statement to retrieve the data from the Trips table in the Compass Travel database.


Understanding basic SQL SELECT statements

The SQL SELECT statement retrieves columns of data from a database. The tabular result is stored in a result table (called the record set).

You use the following SELECT statement to retrieve information from a table:

   SELECT column_name(s) FROM table_name

Consider a table named Clients to hold information about people with the following rows:

LastName | FirstName | Address | City
Jones | Tom | 12 State St | Boston
Adams | Anita | 521 Beacon St | Boston
Green | Peter | 1 Broadway | New York

To select the columns named LastName and FirstName, use the following SELECT statement:

SELECT LastName, FirstName FROM Persons

The results of this SQL statement contains the following data:

LastName | FirstName
Jones | Tom
Adams | Anita
Green | Peter


Using the SQL WHERE clause to limit the rows returned

To conditionally select data from a table, you can add a WHERE clause to the SELECT statement resulting in the following syntax:

SELECT column_name FROM table_name WHERE column condition value

With the WHERE clause, you can use any of the following operators:

Operator | Description
= | Equal
<> | Not equal
> | Greater than
< | Less than
>= | Greater than or equal
<= | Less than or equal
BETWEEN | Between an inclusive range
AND | Joins one or more conditions
OR | Joins one or more conditions
LIKE | Specifies a search for a pattern in a column. You can use a "%" sign to define wildcards (missing letters in the pattern) before and after the pattern.

For example, to select the columns named Last Name and First Name for Clients whose City is Boston, use the following SELECT statement:

SELECT LastName, FirstName FROM Clients Where City = 'Boston'

The results of the preceding SQL statement contains the following data:

LastName | FirstName
Jones | Tom
Adams | Anita

You can compose a WHERE clause with one or more conditions; these are called subclauses. You join subclauses using the operators AND and OR.The AND operator displays a row if ALL conditions listed are true. The OR operator displays a row if ANY of the conditions listed are true. An example of a WHERE clause with multiple subclauses follows:

SELECT LastName FROM Clients Where City = 'Boston' AND FirstName = 'Anita'

The results of the preceding SQL statement contains the following data:

LastName
Adams

Note: The preceding SQL SELECT examples use single quotation marks around the value. SQL uses single quotation marks around text values. Most database systems will also accept double quotation marks. Do not enclose numeric values in quotation marks.


Sorting the results

You use the ORDER BY clause to sort the result rows. The following SQL statement returns an alphabetic list of people sorted by last name then first name from the Clients table:

SELECT * FROM Clients Order By LastName, FirstName

The default is to return the results in ascending order (top to bottom). If you include the DESC keyword in the ORDER BY clause, the rows are returned in descending order (bottom to top).

The following statement returns a reverse alphabetic list of the Clients table:

SELECT * FROM Clients Order By LastName, FirstName DESC

Note: The SQL SELECT statement is quite powerful. There are several other options for retrieving data from a SQL database using the SELECT statement, which are not described in this book. For more information, consult a SQL reference.


Using SQL with cfquery to dynamically retrieve information

Relational database management systems process SQL instructions sent to them from various applications. ColdFusion sends SQL statements to database managers to manipulate data. ColdFusion needs a way to know which database manager to send a specific SQL string for evaluation. In CFML, the cfquery tag serves this purpose. You will use the SQL SELECT statement and the cfquery tag to create a dynamic version of the Trip List page presented earlier in this lesson. In this example, you use cfquery to return all the trip names found in the tripName column within the Compass Travel Trips table. To use the SQL SELECT statement to dynamically retrieve this information, you must execute the SQL SELECT statement between the cfquery start and end tags as follows:

<cfquery name="TripResult" datasource= "CompassTravel">
   SELECT tripName FROM trips
</cfquery>


Displaying the query result using cfoutput

In Chapter 2, you learned that the ColdFusion cfoutput tag is an easy mechanism to display literal text and the contents of variables. Additionally, the cfoutput tag significantly simplifies displaying the results of queries. When used to display the results from a query, the cfoutput tag automatically loops through the record set for you. You simply specify the name of the query in the QUERY attribute of the cfoutput tag:

<cfoutput query="TripResult">

All the code between the cfoutput start and end tags is the output code block. The output code block executes repeatedly, once for each row in the record set. However, if the query returns no rows, ColdFusion skips the code contained in the output code block.

<cfoutput query = "xxx">
   ...output code block...
</cfoutput>


Displaying the column contents from the SQL statement

In CFML you surround variables with pound signs (#) to display their contents using the cfoutput tag. You also use this approach with column names specified in the SELECT statement of a cfquery. For instance, when you want to display the trip names from the SQL query, you would simply use #tripName# within the output code block.

<cfoutput query="TripResult">
   #tripname#
</cfoutput>

For additional information about using SQL with cfquery and cfoutput, see Developing ColdFusion MX Applications with CFML.


Creating a dynamic web page

In the following exercises you will build a dynamic Trip Listing web page that is always current. The first exercise guides you through constructing a query to retrieve information from the database. In the second exercise, you will enhance the query to sort the query results and to display other pertinent trip information.

For your convenience, the following figure shows the Compass Travel Trips table. You can refer to this table to verify the names of the columns you use in the queries in the exercises.

This is a picture of the feature being described.


Exercise: building a query using SQL, cfquery, and cfoutput

Follow these steps to build a query that lists the current trips from the Compass Travel database.

To build the query:

  1. Open an editor and create a new ColdFusion page (.cfm).
  2. At the top of the file, enter the following code to dynamically retrieve the names of the current trips listed in the Compass Travel database:
    3. <cfquery name="TripResult" datasource="compasstravel">
      SELECT tripName FROM trips
</cfquery>
<html>
   <head>
      <title>Trip Listing</TITLE>
   </head>
   <body>
      <h1>Trip List</h1>
      <cfoutput query="TripResult">#tripName#<BR></cfoutput>
   </body>
</html>
  3. Save the file as triplisting.cfm in the my_app directory.
  4. View the triplisting.cfm page in a browser. The page lists all the trip names retrieved from Compass Travel database.


Reviewing the code

The following table describes the code used to build the query:

Code
Explanation
<cfquery name="TripResult"
datasource="CompassTravel">
ColdFusion query named "TripResult". Submits any SQL statement between the cfquery start and end tags to the data source specified in the datasource attribute.
SELECT tripName FROM trips
SQL SELECT statement to retrieve all tripName(s) from the trips table.
<cfoutput query="TripResult">
#tripName#<BR></cfoutput>
Output code block. Displays the value of the column tripName for each row in the result set from the "TripResult" query.


Exercise: enhancing the query

In this exercise you will improve the Trip List page to make it easier for the Compass Travel agents to locate trips. You must make the following improvements:

  • Sort the trip names in alphabetic order.
  • Display the departure date, return date, and price for each trip.
  • Develop a Budget Trip List report that identifies trips that are priced $1500 or less.

To enhance the trip listing query to meet these new requirements, you will modify the query you created in the previous exercise.

Follow these steps to enhance the query to meet the new requirements. Display the triplisting.cfm page in the browser after each step to ensure the corresponding requirement was met.

To enhance the query results:

  1. To sort the trip names in alphabetical order in the triplisting.cfm page, modify the SQL SELECT statement within the cfquery tags as follows:
    2. SELECT tripName FROM trips ORDER BY tripName
  2. To display the departure, return date, and price for each trip, modify the same SQL statement.
    1. Modify the SQL SELECT statement, as follows:
      2.    SELECT tripName, departureDate, returnDate, price
   FROM trips
   ORDER BY tripName
    2. Change the output block (the code immediately preceding the </cfoutput> tag) from just #tripName# to include all three selected fields, as follows:
      3.    #tripName# departs: #departureDate# returns: #returnDate# price:
   #price#<BR>
  3. Create the Budget Trip List report by doing the following:
    1. Modify the SQL SELECT statement, as follows:
      2.    SELECT tripName, departureDate, returnDate, price
   FROM trips
   WHERE price <= 1500
   ORDER BY tripName
    2. Change the heading tag from <h1>Trip List</h1> to <h1>Budget Trip List</h1>.
  4. View the triplisting.cfm in a browser and verify that all the new requirements were met. The revised TripListing.cfm page looks like this:

    5. This is a picture of the feature being described.

    Note that the dates and prices in the preceding listing are not formatted. In Lesson 3 you will enhance the look of this page.


Developing a search capability

The dynamic listings developed in the previous exercise meet many of Compass Travel’s requirements for locating trips. However, what if the number of trips were in the thousands or tens of thousands? Locating the right trip for a customer might be difficult and certainly time consuming. Moreover, it is very hard, if not impossible, to anticipate all the ways that a user might want to search for trips.

A better solution is to provide an interface for the user to specify the search criteria. The results of the user’s criteria selection are then posted to a search results page. The logic contained within the search results page builds the SQL SELECT statement contained in a cfquery tag using ColdFusion string manipulation. Finally, the action page displays the result using the cfoutput tag. This approach of building and executing SQL statements on the fly is called dynamic SQL.


Dynamic SQL

Dynamic SQL is a term used to refer to SQL code your program generates using variables before the SQL is executed. You can use dynamic SQL to accomplish tasks such as adding WHERE clauses to a search based on the fields that the user filled out on a search criteria page.


Designing the search criteria page

When designing the search criteria page, it is a good idea to develop a list of possible queries the user might issue when searching for the records. Since most Compass Travel customers are primarily concerned with trip locations, departure dates, and price, the following is a list of the types of queries the agents are likely to issue at Compass Travel:

  • List the trips located in Hawaii.
  • Identify the trips with a price greater than $3,000.
  • Show the trips departing after 11/11/2002 that are priced less than $2,000.

There are a number of considerations to take into account, when you design a search page to capture the user’s search criteria. Two of the most important considerations are as follows:

  • For which database columns will the user be allowed to specify a search condition?
  • Should the user be allowed to identify which database columns to include in the record set?

In this lesson, the Compass Travel trip coordinator will search the trips based on tripLocation, departureDate, and price. These queryable columns, therefore, will be the only ones contained in the WHERE clause of the generated SQL Statement. Further, the coordinator will have no control over which columns are returned in the record set. The query will always return the same columns to identify a trip:

  • tripName
  • tripLocation
  • departureDate
  • returnDate
  • price
  • tripID

In later exercises, you will reference these columns when you build the SQL SELECT statement for the cfquery in the search action page.


Understanding search query operators

Now that you decided on the queryable columns (tripLocation, departureDate, and price), you can build a simple form that allows the user to enter values for each of these fields. If the user enters a value (for example, Boston) for the tripLocation field and leaves the other two fields blank, the search results page constructs the following SQL statement:

SELECT tripName, tripLocation, departureDate,
   returnDate, price, tripID
FROM trips
WHERE tripLocation = 'Boston'

But, what if the user wants a list of all the trips where the trip location begins with a "B"? SQL is well-suited for this type of query. When designing the Search Criteria page, you must decide which operators to support for each of the queryable columns. The operators that you use depends on the data type of the SQL column.

For example, price is a numeric data type. The user can specify any of the following:

  • price is 5000
  • price less than 600
  • price greater than 1500

Unlike trip location, it is not semantically correct to consider whether a price begins with "B". Typical SQL string operators are equals, starts with, contains, and ends with.

While many more operators are permissible, for simplification, you can use the following the operators for the Compass Travel queryable columns:

Queryable column | Query operators
tripLocation | is, begins with
departureDate | is, before, after
price | is, greater than, less than


Using SQL operators to create a search criteria page

A simple design for a search criteria page presents an operator list and data entry field for each of the queryable columns. Following this pattern, a page to collect the Compass Travel Trip search criteria looks like this:

This is a picture of the feature being described.

Since all the code used to produce the search criteria page is HTML, you are not requested to build this page. You will, however, use this page (tripsearch.cfm) later in this lesson to test the search action page. The source code for the Trip Search form (tripsearch.cfm) is as follows:

<html>
<head>
<title>Trip Maintenance - Search Form</title>
</head>
<body>
<img src="images/tripsearch.gif">
<!--- Search form --->
<form action="tripsearchresult.cfm" method="post">
<table>
   <!--- Field: tripLocation --->
   <tr>
      <td>   Trip Location
      </td>
      <td>
         <select name="tripLocationOperator">
            <option value="EQUALS">is
            <option value="BEGINS_WITH">begins with
         </select>
      </td>
      <td>
         <input type="text" name="tripLocationValue">
      </td>
   </tr>
   <!--- Field: departureDate --->
   <tr>
      <td>   Departure Date
      </td>
      <td>
         <select name="departureOperator">
            <option value="EQUALS">is
            <option value="BEFORE">before
            <option value="AFTER">after
         </select>
      </td>
      <td>
         <input type="text" name="departureValue">
         </td>
   </tr>
   <!--- Field: price --->
   <tr>
      <td>Price
      </td>
      <td>
         <select name="priceOperator">
            <option value="EQUAL">is
            <option value="GREATER">greater than
            <option value="SMALLER">smaller than
         </select>
      </td>
      <td>
         <input type="text" name="priceValue">
      </td>
   </tr>
</table>
<p>
<input type="submit" value="Search">
</form>
</body>
</html>


Reviewing the code

The following table describes the search criteria code and its function:

Code
Explanation
<form action="tripsearchresult.cfm" method="post">
Identifies tripsearchresult.cfm as the search action page. Results of user entry are passed to the search action page.
<select name="tripLocationOperator">
<option value="EQUALS">is
<option value="BEGINS_WITH">begins with
</select>
Builds a drop-down list offering the query operators for tripLocation. There must one operator list box for each queryable column.
<input type="text" name="tripLocationValue">
Input text control to capture value to test. There is one text control for each queryable column.


Building the Search Results page

Based on the queryable columns identified earlier, the SQL query to display the search results would look like this:

SELECT tripName,  tripLocation, departureDate, returnDate, price, tripID
FROM trips

The purpose of the Trip Search form is to supply the data needed to build the WHERE clause to finish this SQL SELECT statement and constrain the query according to the user’s input.

When the user enters the search criteria on the Trip Search form and clicks the Search button, the form fields are then posted to the Trip Search Results page. The posted field values compose the WHERE clause in the SQL SELECT statement. The following example lists the WHERE clauses that can be generated depending on the criteria set on the search page:

WHERE tripLocation = 'China'
WHERE tripLocation Like 'C%'
WHERE tripLocation = 'China'
   AND departureDate > 1/1/2001
   AND price < 1500

In the previous example, the SQL AND operator joins the search condition clauses. To simplify the trip search example, you will use the SQL AND operator to combine all the search condition clauses. A more sophisticated search criteria page might present the user a choice of using AND or OR to connect one search criterion with the others.

The search action page uses a SQL SELECT statement to display an HTML table with the results of the user query using the cfoutput block.


Building the WHERE Clause with the cfif and cfset

The WHERE clause in a SQL SELECT is a string. You use the CFML cfset and cfif tags to conditionally build the WHERE clause depending on values passed to the search action page. The cfset statement creates a new variable or changes the value of an existing variable. For example, to create a variable named color and initialize its value to red you use the following statement:

<cfset color = "red">

The cfif tag instructs the program to branch to different parts of the code depending on whether a test evaluates to True or False. For example, to have some code execute if the color variable is equal to red, and other code execute if it is not, you use the following pseudocode:

<cfif color EQ "red">
... statements for color red
<cfelse>
... statements for other than red
</cfif>

Building a SQL WHERE clause in code is largely an exercise in string concatenation. The & operator combines two strings in ColdFusion. For example, the following code snippet:

<cfset FirstName = "Dylan">
<cfset LastName = "Smith">
<cfset FullName = FirstName & " " & LastName>
<cfoutput>My name is #FullName#.</cfoutput>

results in the following text:

My name is Dylan Smith.

For each search criterion on the Trip Search form, the code within the Trip Search Results page must do the following:

  • Verify that the user entered data in the search criterion’s value field using the cfif tag; for example <cfif Form.tripLocationValue GT "">
  • If data was entered, construct a WHERE subclause by concatenating the following:
    • the SQL keyword AND
    • the corresponding SQL column name (in the Trip Search example, tripLocation) for the search criterion.
    • the SQL operator equivalent of the search query operator
    • the test value entered by the user

The following code shows the creation of the WHERE subclause:

<cfif Form.tripLocationOperator EQ "EQUALS">
   <cfset WhereClause = WhereClause & " AND tripLocation = '" &
form.tripLocationValue & "'" >
<cfelse>
   <cfset WhereClause = WhereClause & " AND tripLocation like '" &
form.tripLocationValue & "%'" >
</cfif>

When you test for a string column within the WHERE clause of the SQL SELECT statement, you must enclose the test value in quotation marks.

When you use a variable to construct a WHERE clause you must preserve the quotation marks so that the database server does not return an error. To preserve the quotation marks, you must use the ColdFusion PreserveSingleQuotes function.


Constructing the initial Trip Search Results page

The following code shows how to construct the tripLocation SQL WHERE subclause. Specifically, it uses a dynamic SQL SELECT statement built from parameters from the Trip Search page to display the search results.

As mentioned previously, the SQL SELECT statement uses quotation marks to surround string variable values. Unfortunately, embedded quotation marks can cause problems when posting data to a web server. Normally, ColdFusion adds an escape character to a string that contains a quotation mark so that an error is not generated from the web server. The PreserveSingleQuotes function prevents ColdFusion from automatically escaping single quotation marks contained in the variable string passed to the function.

<!--- Create Where clause for query from data entered thru search form --->
   <cfset WhereClause = " 0=0 ">
<!--- Build subclause for trip location --->
   <cfif Form.tripLocationValue GT "">
      <cfif Form.tripLocationOperator EQ "EQUALS">
         <cfset WhereClause = WhereClause & " and tripLocation = '" &
form.tripLocationValue & "'" >
      <cfelse>
         <cfset WhereClause = WhereClause & " and tripLocation like '" &
form.tripLocationValue & "%'" >
      </cfif>
   </cfif>
<!--- Query returning search results --->
      <cfquery name="TripResult" datasource="compasstravel">
         SELECT tripName,  tripLocation, departureDate, returnDate, price, tripID
         FROM trips
         WHERE #PreserveSingleQuotes(WhereClause)#
      </cfquery>
<html>
<head>
<title>Trip Maintenance - Search Results</title>
</head>
<body>
   <img src="images/tripsearchresults.gif">
   <table border="0" cellpadding="3" cellspacing="0">
      <tr bgcolor="Gray">
         <td>   Trip Name
         </td>
         <td>   Location
         </td>
         <td>   Departure Date
         </td>
         <td>   Return Date
         </td>
         <td>   Price
         </td>
      </tr>
      <cfoutput query="TripResult">
         <tr>
            <td>   #tripName#
            </td>
            <td>   #tripLocation#
            </td>
            <td>   #departureDate#
            </td>
            <td>   #returnDate#
            </td>
            <td>   #price#
            </td>
         </tr>
      </cfoutput>
</table>
</body


Reviewing the code

The following table describes the code used to build the tripLocation WHERE subclause:

Code
Explanation
<cfset WhereClause = " 0=0 ">
The cfset tag initializes the WhereClause variable to hold the WHERE clause to be constructed. The initial value is set to "0=0", so that the WHERE clause has at least one subclause in case the user enters no search criteria.
<cfif Form.tripLocationValue GT "">
The cfif tag tests to see if user entered anything in the Value input box for tripLocation criterion.
SELECT tripName,  tripLocation,
departureDate, returnDate, price, tripID
FROM trips
WHERE #PreserveSingleQuotes(WhereClause)#
SQL query to execute. PreserveSingleQuotes ColdFusion function ensures that quotation marks will passed to the database server as intended.

Note that the preceding code only builds the tripLocation subclause. In the following exercise you will add code for the other two queryable columns, departureDate and price.


Completing the Trip Search Results page

In the following exercises you will test and modify tripsearchresults.cfm. In the first exercise, you will test the Trip Search Results page by entering criteria on the Trip Search form and inspecting the results. In the second exercise, you will finish the code to construct the complete WHERE clause for all three queryable columns from the Trip Search form.


Exercise: testing the Trip Search Results page

Follow these steps to test the Trip Search Results page:

  1. Copy the tripsearch.cfm and tripsearchresult.cfm files from the solutions directory to the my_app directory.
  2. View the tripsearch.cfm from the my_app directory in your browser and do the following:
    1. In the Trip Location drop-down list box select the Begins With option, and enter the value C in the text box.
    2. Click Search.

      3. The Trip Results page displays several entries as follows:

      This is a picture of the feature being described.

    3. Notice in the Trip Results page that only one trip has a trip location of China.
    4. Click the Back button in your browser to return to the Trip Search page.
  3. In the Trip Location drop-down list box of the Trip Search page, select the Is option, enter the value China, then click Search.

    4. The Trip Results page displays only one entry for the trip to China in the HTML table.

  4. Verify that the other criteria (departure date and price) are not taken into consideration yet as follows:
    1. Click the Back button in the browser to return to the Trip Search page.
    2. In the Departure Date drop-down list box, select Before, enter 1/1/1900 as the date, and select Smaller Than 0 for the price.

      3. Obviously, either of these conditions would produce a results page with no rows.

    3. Click the Search button.

      4. The Search Result page should be identical to Step 3 because the code to build the WHERE clause in the Trip Results page does not include departure date and price.


Exercise: enabling the departure and price criteria on the Trip Search form

In this exercise you will modify the Trip Search Results page to add the criteria needed for the departure and price query.

To enable the departure and price criteria:

  1. In an editor, open the tripsearchresult.cfm page in the my_app directory, then locate the following comment line:
    2.    <!--- Query returning search results --->
  2. To build the departureDate WHERE subclause, enter the code in the following table immediately following the comment line.

    For
    Enter this code
    Windows users, using the MS Access database file
    <!--- Build subclause for departureDate --->
    <cfif Form.departureValue GT "">
    <cfif Form.departureOperator EQ "EQUALS">
    <cfset WhereClause = WhereClause & " and departureDate = " & Form.departureValue>
    <cfelseif Form.departureOperator EQ "AFTER">
    <cfset WhereClause = WhereClause & " and departureDate > " & Form.departureValue>
    <cfelseif Form.departureOperator EQ "BEFORE">
    <cfset WhereClause = WhereClause & " and departureDate < " & Form.departureValue>
    </cfif>
    </cfif>
    UNIX users, using the Pointbase database file
    <!--- Build subclause for departureDate --->
    <cfif Form.departureValue GT "">
    <cfif Form.departureOperator EQ "EQUALS">
    <cfset WhereClause = WhereClause & " and departureDate = Date '" & Form.departureValue & "'">
    <cfelseif Form.departureOperator EQ "AFTER">
    <cfset WhereClause = WhereClause & " and departureDate > Date '" & Form.departureValue & "'">
    <cfelseif Form.departureOperator EQ "BEFORE">
    <cfset WhereClause = WhereClause & " and departureDate < Date '" & Form.departureValue & "'">
    </cfif>
    </cfif>

  3. To build the price WHERE subclause, enter the following code after the code you entered in step 2.
    4.    <!--- Build subclause for price--->
   <cfif Form.priceValue GT "">
      <cfif Form.priceOperator EQ "EQUALS">
         <cfset WhereClause = WhereClause & " and price = " & form.priceValue>
      <cfelseif Form.priceOperator EQ "GREATER">
         <cfset WhereClause = WhereClause & " and price > " & form.priceValue>
      <cfelseif Form.priceOperator EQ "SMALLER">
         <cfset WhereClause = WhereClause & " and price < " & form.priceValue>
      </cfif>
   </cfif>
  4. Verify that the price and departureDate are now considered in the query, as in step 4 in the previous exercise:
    1. Open the tripsearch.cfm page in the my_app directory in your browser.
    2. In the Departure Date drop-down list box, select Before, enter 1/1/1900 as the date, and select Smaller Than 0 for the price.
    3. Click the Search button.

      4. Now, because the departure date is considered in the query, there are no rows returned.

      Note: If you planned to use many more fields as search criteria, the approach used to add departure date and price criteria to the Trip Search form is not the most elegant solution. A generic routine to handle WHERE clause string construction based on specific data types could reduce the code and be a more extensible solution then the one presented here. This more extensible approach is beyond the scope of this tutorial, however.


Summary

This lesson described how to access a relational database using ColdFusion. You used the SQL SELECT statement and the cfquery and cfoutput tags to display trip lists. You built a search tool that dynamically builds a WHERE clause of the SQL SELECT statement using cfif and cfset tags. To ensure that the SQL statement remains intact, you used the PreserveSingleQuotes CFML function.


In the next lesson

In the next lesson, you will build the main navigation page for the Trip Maintenance application. This page will display detail information about the currently selected trip. Additionally, it will provide buttons to do trip maintenance and browsing through the trips table. You will also link the trip search facility that you built in this lesson to the main page that you will build in the next.

Previous


Creating a Main Application Page

In this lesson you will enhance the Compass Travel Trip Maintenance application. The exercises in this lesson guide you through the following steps:

  • Transforming the search facility that you built in the previous lesson into a drill-down facility for trip queries
  • Creating a Trip Detail page to display complete details of a trip
  • Implementing a link from Trip Detail page to the search facility
  • Converting the Trip Detail page into the main application page by including buttons for navigating to other pages and browsing trip records in the database

This lesson explains how to do the following tasks:

  • Use URLEncodedFormat to safely link the Search Results page to the Trip Detail page.
  • Use the DateFormat and DollarFormat functions to properly format date and dollar variables.
  • Use the MOD function and a query variable to properly alternate the back color of rows in the Trip Search Results table.
Next


ColdFusion tags and functions introduced in this lesson

The following table identifies the ColdFusion tags and functions that you use in this lesson to enhance the sample ColdFusion application:

Element | Type | Brief description
IsDefined | Function | Evaluates a string value to determine whether it represents an existing variable. Returns True if the variable is found, False if not found.
DollarFormat | Function | Returns a number as a string formatted with two decimal places, thousands separator, and dollar sign. If the specified number is negative, parentheses are used.
DateFormat | Function | Returns a formatted date/time value. If no mask is specified, DateFormat returns the date value in the dd-mmm-yy format. DateFormat supports dates that have the U.S. date format.
URLEncodedFormat | Function | Converts a text string into a string that can safely be used in a URL.


Enhancing the Trip Maintenance application

In this lesson you will enhance the Trip Maintenance application that you created in Lesson 2. You will modify the application to include a main application page that lets Compass Travel employees do these tasks:

  • View additional details about a trip.
  • Scan records in the Trips database table.
  • Modify or search for records in the Trips database table.

The following list identifies the application components that you will create in this lesson:

  • Trip Detail Page. The Trip Detail page displays additional information about a trip that was initially selected from the Trip Search Results page.

    • This is a picture of the feature being described.

  • Enhanced Trip Search Results page. The original purpose of the Trip Search Results page in Lesson 2 was to display the results of a trip search. In this lesson, you will enhance this page to provide a useful drill-down mechanism for accessing additional information about trips that meet the search criteria.

    • This is a picture of the feature being described.

  • Main Application page In the beginning of this lesson, you will develop the Trip Detail page (see the following figure). Later in this lesson, you will convert the Trip Detail page into the main Trip Maintenance application page. The main application page will include additional buttons for navigating to other ColdFusion pages and browsing the trip database records.

    • This is a picture of the feature being described.

The primary users of these components will be the Compass Travel coordinators and agents, not the general public.


Showing additional trip details

By design, the Trip Search Results page displays a subset of the information about a trip. To get additional information about any of the trips displayed, the user should be able to click on any row to display the detailed trip data.

In the following exercise, you build a Trip Detail page to provide all the information about a particular trip that is stored in the Compass Travel trips database. The following figure shows an example of the Trip Detail page that you will build:

This is a picture of the feature being described.

After you complete the Trip Maintenance application in this tutorial, you will use this Trip Detail page in several ways:

  • You can call the TripDetail page directly by typing in the address of the page with an ID. For example, to view trip information for Rio Cahabon Rafting with tripID 24, you open a browser and enter the following URL:
    • http://localhost/cfdocs/getting_started/my_app/tripdetail.cfm?ID=24
  • You can navigate to the Trip Detail page by creating a hyperlink from the trip name on the Trip Results page. This will offer the user drill-down capability when searching for trips. You will link the Trip Results page and the Trip Detail page in one of the exercises in this lesson.
  • You can use browse buttons on the Trip Detail page to navigate the Trips table row by row. You will implement this navigational feature in the next lesson.


Exercise: building a Trip Detail page

Follow these steps to build a Trip Detail page.

To build a Trip Detail page:

  1. Open your editor and create a new ColdFusion page. Remove any lines if your editor adds.
  2. To create a query to select a single trip from the Trips table, enter the following code:
    3. <cfquery name="TripQuery" dataSource="compasstravel" maxRows=1>
SELECT tripID, tripName, tripDescription, tripLocation, departureDate,
returnDate, price, tripLeader, photo, baseCost, numberPeople, depositRequired
FROM TRIPS
<cfif IsDefined("URL.ID")>
WHERE tripID = #URL.ID#
</cfif>
</cfquery>
  3. To output the results from the query, append the following cfoutput code after the code you added in step 2.
    4. <cfoutput query="TripQuery">
   <img src="images/tripmaintenance.gif">
</cfoutput>
  4. To display the data fields on the Trip Detail page, place the following code above the </cfoutput> tag you added in step 3. Alternatively, you can copy this HTML code from the tripdetail.txt file in the solutions directory.
    5. <table>
   <tr>
      <td valign="top">   Trip Name:
      </td>
      <td>   #tripName#
      </td>
   </tr>
   <tr>
      <td valign="top">   Description:
      </td>
      <td>   #tripDescription#
      </td>
   </tr>
   <tr>
      <td valign="top">   Location:
      </td>
      <td>   #tripLocation#
      </td>
   </tr>
   <tr>
      <td valign="top">   Departure Date:
      </td>
      <td>   #departureDate#
      </td>
   </tr>
   <tr>
      <td valign="top">   Return Date:
      </td>
      <td>   #returnDate#
      </td>
   </tr>
   <tr>
      <td valign="top">   Price:
      </td>
      <td>   #price#
      </td>
      </tr>
   <tr>
      <td valign="top">   Base Cost:
      </td>
      <td>   #baseCost#
      </td>
   </tr>
   <tr>
      <td valign="top">   Trip Leader:
      </td>
      <td>   #tripLeader#
      </td>
   </tr>
   <tr>
      <td valign="top">   Number People:
      </td>
      <td>   #numberPeople#
      </td>
   </tr>
   <tr>
      <td valign="top">   Deposit Required:
      </td>
      <td>   #depositRequired#
      </td>
   </tr>
   <tr>
      <td valign="top">   Photo File:
      </td>
      <td>   #photo#
      </td>
   </tr>
</table>
  5. To provide a title that appears on the browser window, insert the following HTML code before the <cfoutput query = "TripQuery"> line:
    6. <html><head>
   <title> Trip Maintenance - View Record </title>
</head>
<body>
  6. Insert the ending body and html tags at the end of the page:
    7. </body>
</html>
  7. Save the file as tripdetail.cfm in the my_app directory.
  8. The Rio Cahabon Rafting trip has an tripID of 24. To view the trip detail for the trip in your browser enter one of the following URLs::

    Web server configuration
    URL
    For stand-alone ColdFusion web server configuration
    http://localhost:8500/cfdocs/getting_started/my_app/tripdetail.cfm
    For local third-party web server configuration
    http://localhost/cfdocs/getting_started/my_app/tripdetail.cfm

    9. The following page shows the expected result:

    This is a picture of the feature being described.


Reviewing the code

The following table describes the ColdFusion code used to build the Trip Detail page:

Code
Explanation
<cfquery name="TripQuery"
dataSource="CompassTravel" maxRows=1>
The cfquery tag includes a maxRows attribute. This attribute limits the number of result rows brought back from the database. In the Trip Detail page, we want to only show a single row at a time, therefore, maxRows is set to 1.
<cfif IsDefined("URL.ID")>
   WHERE tripID = #URL.ID#
</cfif>
The URL.ID specifies a parameter that can be contained within the URL that requests this page. If the ID parameter is passed within the URL, it is used in the SQL query to identify the tripID to SELECT. You can use the CFML function IsDefined to determine if a parameter is passed within the URL. It can also be used to determine if the user has entered data in form fields prior to the form post action.

As you can see, you can build comprehensive database query applications using CFML and dynamic SQL. To further test the new Trip Detail page that you created, you will link it to the search facility that you built in Lesson 2. However, before you link the search facility you built in Lesson 2, you need to understand a potential security risk using dynamic SQL. The following section describes this risk and how to code around it.


Avoiding the potential security risk when using dynamic SQL

To reduce round trips between the client and the database server, many SQL database servers permit the client to submit multiple SQL statements in a single request, separated by a semicolon (;). For these database managements systems, the following SQL request is valid:

DELETE from trips where tripLocation = 'China'; SELECT tripName from trips

This request may be an efficient way to list the trips that remain after the database management system removes the China trip. Problems arise when the SQL statement is built dynamically.

In the Trip Maintenance application, when the client program or user passes an ID in the URL that calls the Trip Detail page, the page displays the relevant trip information. The following code builds the correct WHERE clause supporting this behavior:

<cfif IsDefined("URL.ID")>
   WHERE tripID = #URL.ID#
</cfif>

If a user called the Trip Detail page using the following statement:

http://localhost/cfdocs/getting_started/my_app/tripdetail.cfm?ID=24;DROP+trips

the SQL database management system executes the proper SQL SELECT statement, then immediately erases the Trips table from the database.


Protecting your application

To ensure that your application is protected from such an attack, you can exploit the fact that the ID must be a numeric value. The CFML Val function returns the numeric value at the beginning of a string expression. You can use the Val function as follows:

<cfif IsDefined("URL.ID")>
   WHERE tripID = #Val(URL.ID)#
</cfif>

Now if non-numeric data is passed within the URL ID field, the Val statement returns 0, and the trip with ID 0 displays (if one exists). If the user enters the previously cited URL (http://localhost/cfdocs/getting_started/my_app/tripdetail.cfm?ID=24;DROP+trips), the application ignores the non-numeric values and displays the trip information of trip ID 24.

Warning:The exercises in this tutorial ignore the dynamic SQL risk from attack. You must use the Val function in your applications to eliminate the risk.


Linking the Search Results page to the Trip Detail page

In the next exercise you will modify the Trip Search Results page to let the user view the details of any trip. To do this, you will convert the trip name entries in the results page to links, which will display the trip’s detailed information in the detail page.


Exercise: linking the Search Results page with the Trip Detail page

Use the following steps to link the Trip Search Results page (tripsearchresult.cfm) to the Trip Detail page (tripdetail.cfm).

To create links between pages:

  1. Open the tripsearchresult.cfm page from the my_app directory and replace the #tripName# in the cfoutput block with the following code:
    2. <a href="tripdetail.cfm?ID=#URLEncodedFormat(tripID)#">
#tripName# </a>

    Note: The URLEncodedFormat is a ColdFusion function that returns a URL-encoded string. Spaces are replaced with %20, and nonalphanumeric characters with equivalent hexadecimal escape sequences. The function lets you pass arbitrary strings within a URL, because ColdFusion automatically decodes URL parameters that are passed to the page.
  2. Save the file and view the tripsearch.cfm page from the my_app directory in your browser.
  3. In the Trip Location drop-down list box, select Begins With and type the value C in the trip location text box then click Search.

    4. The Trip Search Results page displays a hyperlink for each trip name listed, as the following figure shows:

    This is a picture of the feature being described.

  4. To view the Trip Detail page for a trip, click on the trip name.

You might notice that the dates and prices in both the Trip Detail and Trip Search Results pages are unformatted. You will improve the appearance of the application in the next exercise.


Enhancing the look of the search results and detail pages

The Trip Maintenance search now provides a useful drill-down mechanism for locating trips. While this application is functionally sound, the appearance of the dates and dollar amounts could be improved.

ColdFusion provides several functions to improve the application appearance. The DateFormat and DollarFormat functions format dates and currency variables. ColdFusion provides.

Another part of the application that could be improved is the Trip Search Results table. In a large list, it is sometimes difficult to correctly read the contents of a row in the middle of the table because it is sandwiched between two other rows. To avoid mistakes in reading the table, it would be helpful to alternate the background color of each row in the table.

The HTML table row <tr> tag has a bgcolor attribute to change the background color for a given row. To highlight every other row, the background color could be changed alternatively to yellow or white. To change the background color for each row, you must determine whether the row is an odd or even row. Therefore, you must obtain the sequence number of the current row and test if it is evenly divisible by 2.

As described in Chapter 2, ColdFusion offers a modulus function (MOD) that returns the remainder (modulus) after a number is divided by a divisor; for example,10 MOD 3 is 1.

If the MOD function returns a value greater than 0, a cfif test of its result evaluates to True. If the MOD function returns 0, the cfif check fails.

The following example uses the MOD function to alternate the background color of table rows:

<cfoutput query="tripResult">
<cfif CurrentRow Mod 2>
   <cfset BackColor="White">
<cfelse>
   <cfset BackColor="Yellow">
</cfif>
<tr bgcolor= "#BackColor#">

Notice that the MOD function uses a variable called CurrentRow. Notice also that CurrentRow is not defined anywhere in tripsearchresult.cfm. The CurrentRow variable is one of a few variables that ColdFusion automatically exposes that provide information about the query. These variables are often called query variables.


Query variables

In addition to using the cfquery tag to return data from a ColdFusion data source, you also can use it to return information about a query. To do this, the cfquery tag creates a query object, providing information in query variables as described in the following table:

Variable Name | Description
query_name.recordCount | The number of records returned by the query.
query_name.currentRow | The current row of the query being processed by cfoutput.
query_name.columnList | A comma-delimited list of the query columns.

When a query variable is referenced within a cfoutput block, the qualifying query_name is assumed to be the query identified in the QUERY attribute of the cfoutput tag and does not need the qualifier query_name. That is why the CurrentRow variable is unqualified in the previous modulus code example.

For more information about using the modulus function or query variables in ColdFusion applications, see Developing ColdFusion MX Applications with CFML.


Exercise: formatting the display

In this exercise, you format the currency and date fields in the Trip Search Results page and the Trip Detail page. Additionally, you modify the Trip Search Results page to alternate the background color of the result table rows.

To format the table:

  1. To format the Trip Detail page dollar and date fields, open the tripdetail.cfm in the my_app directory in your editor and make the following changes:

    Existing code
    Change to
    #departureDate#
    #dateformat(departureDate, "mm/dd/yyyy")#
    #returnDate#
    #dateformat(returnDate, "mm/dd/yyyy")#
    #price#
    #dollarformat(price)#
    #baseCost#
    #dollarformat(baseCost)#

  2. To format the currency and date fields on the Trips Search Results page, open the tripsearchresult.cfm in your editor and make the same changes for departureDate, returnDate, and price as in step 1.
  3. To alternate the background color of the rows of the search results table, delete the table row tag <tr> that immediately follows the <cfoutput query="TripResult">, and replace it with the following code:
    4. <cfif CurrentRow Mod 2>
   <cfset BackColor="White">
<cfelse>
   <cfset BackColor="Yellow">
</cfif>
<TR bgcolor= #BackColor#>
  4. Save the files then open your browser and navigate to the tripsearch.cfm page in the my_app directory. Again, enter Begins With and C in the location search criteria, and click Search.

    5. The Trip Search Results page appears:

    This is a picture of the feature being described.

  5. In the Trip Search Result page, click the link for Riding the Rockies.

    6. The properly formatted Trip Detail page appears:

    This is a picture of the feature being described.


Creating the main application page from the Trip Detail page

To this point in the tutorial, you created a very useful drill-down query facility. Compass Travel trip coordinators can produce lists required by management and easily locate and display information about any trip. There are several requirements that were identified in Lesson 1, however, that you have not addressed: the ability to browse through the Trips table, and the ability to add, delete, and edit trip information.

The trip coordinator must be viewing the details of a specific trip to edit trip information or delete a trip. The Trip Detail page provides this trip-specific detail information. Therefore, you will use the Trip Detail page as the main Trip Maintenance application page.

You will modify the Trip Detail page so that it can act as a main switchboard to accomplish this additional functionality. The Trip Detail page shows information about a single trip. You will convert the Trip Detail page into the main application page by adding the following functionality:

  • Navigation buttons to browse the database
  • Database maintenance buttons to edit, delete, or add new trips
  • An additional button to launch the search facility


Adding navigation buttons to browse database

The drill-down search function developed in the last exercise is very useful when the user knows some search criteria to enter. Unfortunately, however, flipping back and forth between the results page and the detail page to navigate through a record set can be tedious. Moreover, on occasion the trip coordinator might want to browse the Trips database just to check for anomalies or to become familiar with its contents. In these cases, the user does not know the criteria to search for in advance.

For example, an anomaly may exist on any trip record, the trip coordinator would have no idea what search criteria to specify on the search form to find these problem records. To solve this problem, the browse function gives the coordinator the ability to navigate sequentially through the trips table using the single record trips display. The following figure shows the navigation buttons. The label under each button describes which row to display relative to the currently displayed row:

This is a picture of the feature being described.


Exercise: adding navigation buttons to the Trip Detail page

In this exercise, you use the HTML form and input tags to add the navigational buttons to the Trips Detail page.

To add navigation:

  1. Open the tripdetail.cfm in the my_app directory in your editor.
  2. To implement the trip navigation buttons, insert the following code between the
    </table> and</cfoutput> tags in the tripdetail.cfm file:
    3. <form action="navigationaction.cfm" method="post">
   <input type="hidden" name="RecordID" value="#tripID#">
   <!--- graphical navigation buttons --->
   <input type="image" name="btnFirst" src="images/first.gif">
   <input type="image" name="btnPrev" src="images/prev.gif">
   <input type="image" name="btnNext" src="images/next.gif">
   <input type="image" name="btnLast" src="images/last.gif">
</form>

    Note: Notice that the current trip record ID (tripID) is hidden within the form code. This is desirable because the action page must have the current record ID in order to build the query that navigates to the appropriate record in the trips database table.
  3. Save the file and view the updated tripdetail.cfm page in a browser.

    4. The Trip Search Results page appears:

    This is a picture of the feature being described.

  4. Test the buttons by clicking any navigation button.

    5. An error occurs because the navigation action page (navigationaction.cfm) does not exist. The navigation action page processes the navigation button requests. You will build the navigation action page in the next lesson.


Reviewing the code

The following table describes the navigation code in the Trip Detail page:

Code
Explanation
<form action="navigationaction.cfm" method="post">
Form tag identifying navigationaction.cfm to handle record navigation.
<INPUT type="hidden" name="RecordID" value="#tripID#">
Hidden RecordID field with the value of the current tripID.
<input type="image" name="btnFirst" src="images/first.gif">
<input type="image" name="btnPrev" src="images/prev.gif">
<input type="image" name="btnNext" src="images/next.gif">
<input type="image" name="btnLast" src="images/last.gif">
Navigation buttons are image type HTML input tags.


Adding database maintenance buttons

The search and sequential navigation capabilities are features for locating Compass Travel trips. After the trip coordinator locates a trip, they must be able to modify or delete the trip. Additionally, when viewing the detail for a trip, they must be allowed to add a new trip or use the search facility. To enable trip coordinators to do this, you will add the following buttons to the Trip Detail page:

This is a picture of the feature being described.

As described earlier, it is important to pass the current record ID (tripID) to the action page to build the proper SQL statement to process the navigation button requests. It is also important to pass the current record ID to the Maintenance Action page. Therefore, you will use an HTML input tag to hide the current recordID and post it to the maintenanceaction.cfm page.


Exercise: Add Maintenance Buttons to Trip Detail Page

Follow these steps to add the database maintenance buttons to the Trip Detail page.

To add maintenance buttons:

  1. In your editor, open the tripdetail.cfm from my_app subdirectory.
  2. Enter the following code immediately after the <cfoutput query="TripQuery"> tag in the tripdetail.cfm file:
    3. <form action="maintenanceaction.cfm" method="post">
   <input type="hidden" name="RecordID" value="#tripID#">
   <input type="submit" name="btnAdd" value="   Add    ">
   <input type="submit" name="btnEdit" value="  Edit  ">
   <input type="submit" name="btnDelete" value="Delete">
   <input type="submit" name="btnSearch" value="Search">
</form>

    Note: The current trip record ID (tripID) is in a hidden field in the form code. This field provides the action page with current record ID that it must have in order to build the query to access the appropriate record in the Trips database table.
  3. Save the file and view the updated tripdetail.cfm page in a browser (http://localhost/CFDOCS/getting_started/my_app/tripdetail.cfm).

    4. The page appears as follows:

    This is a picture of the feature being described.

  4. Click Search or Delete to test the database maintenance buttons.

    5. An error occurs because the Maintenance Action page does not exist. The Maintenance Action page is required to process the maintenance button requests. You will develop this page in the next lesson.


Summary

In this lesson, you transformed the search facility you built in Writing Your First ColdFusion Application into a drill-down facility for trip queries. You built a Trip Detail page to show more information about a particular trip. You also formatted the Trip Search Results and Trip Detail pages using the CFML DollarFormat and DateFormat functions. You linked the Trip Search Results page with the Trip Detail page. You used the URLEncodedFormat CFML function to ensure that data was correctly from one page to the other. Finally, by adding trip maintenance and navigation buttons, you converted the Trip Detail page into the main Trip Maintenance application page.


In the next lesson

In the next lesson, you will build the action pages required to implement the navigation and maintenance buttons on the main Trip Maintenance application page.

Previous


Validating Data to Enforce Business Rules

In this lesson, you will enhance the Compass Travel Trip Maintenance application. The exercises in this lesson will guide you through the steps of enhancing the application to provide a page for the trip coordinator to add new trip offerings and update existing trips. Further, you will add logic to validate that data entered against Compass Travel business rules.

This lesson explains how to do the following tasks:

  • Create a data entry form to capture user input information
  • Develop an action page to process posted form variables
  • Validate captured data in three ways
Next


ColdFusion tags and functions introduced in this lesson

The following table identifies the ColdFusion tags and functions that you use in this lesson to enhance the ColdFusion application:

Element
Type
Description
cfform
Tag
Builds a form with CFML custom control tags that provide more functionality than standard HTML form input elements.
cfinput
Tag
Use inside cfform to place radio buttons, checkboxes, or text boxes. Provides input validation for the specified control type.
cfselect
Tag
Used inside cfform, cfselect lets you construct a drop-down list box form control. You can populate the drop-down list box from a query, or use the option tag. You further use option elements to populate lists. The syntax for the option tag is the same as for its HTML counterpart.
FileExists
Function
Returns True if the file specified in the argument exists; otherwise it returns False.


Enhancing the Trip Maintenance application

In this lesson and the next, you will create the code to implement the remaining maintenance buttons on the main Trip Maintenance application page. The remaining buttons are Add and Edit.

You will develop the data entry form to capture new trip information and validate the data entered against Compass Travel business rules. You will then modify the data entry form to edit existing trips. In the next lesson, you will continue to build on this application by adding logic to insert and update the data to the Compass Travel database.

The following list identifies the trip edit components that you will create in this lesson.

  • Trip Edit page You will create the Trip Edit page (see the following figure) bto add new trips and edit existing trips. The page will be launched from the Add and Edit buttons on the main Trip Maintenance application page (tripdetail.cfm). The fields required to capture trip information are the same as those on the Trip Detail page that you used to display trip information in Lesson 3.

    • This is a picture of the feature being described.

  • Trip Edit Action page You will develop an action page that will insert or update trip data passed from the Trip Edit page into the trips table of the Compass Travel database. In this lesson you will only add the logic to validate the data entered on the Trip Edit page.


Using an HTML form to collect data

Based on the data requirements determined in Lesson 1, the following figure shows the Trip Edit data collection page:

This is a picture of the feature being described.


Exercise: view the source and test the Trip Edit page

To view the source and test the Trip Edit data collection form:

  1. Open an editor, then locate and open the file tripedit1.cfm in the solutions directory \cfdocs\getting_started\solutions under your web root directory.
  2. Review the HTML source code used to create the Trip Edit page. If you are not fluent in HTML, the following table explains the use of some of the HTML tags in the Trip Edit page. For more information on HTML, consult any HTML primer.

    Tag
    Description
    Form
    You create a data entry form by using the form tag. The form tag takes two tag attributes; for example:
    <form action="tripeditaction.cfm" Method= "Post">
    Here, the action attribute specifies the name of the ColdFusion file that the web server will navigate to in response to the form’s submission. The method attribute specifies how data is returned to the web server. Submit all ColdFusion forms using the Post method attribute.
    Table
    You can format a data entry form and display its controls neatly, by using the table tag, table, table row tag, tr, and the table data tag, td.
    Form Controls
    The form requires controls to collect and submit user input. There are a variety of types of form controls you can use. For this lesson, you will use the following controls:
    • <input>. Accepts text answers such as Trip Name and Trip Price.
    • <input type=checkbox>. Asks yes or no questions, such as Deposit Required?
    • <select>,<option>. Provides user with a list of possible answers such as the event type (Mountain Biking, Surfing, and so on).
    • <textarea>. Gathers user input on multiple lines such as for the Trip Description.
    • <input type=submit>. Posts the information collected to the server.

  3. Save the file as tripedit.cfm to the my_app directory.
  4. View the tripedit.cfm in a browser and test the form by entering a trip name in the Trip Name field then clicking Save. An error occurs.
  5. View the form source (tripedit.cfm) in an editor to try to determine the cause of the error. Notice that the <form> tag on line 6 of the source code has an action attribute. This attribute indicates the page to receive the form values posted by the tripedit.cfm page. Since the page, tripeditaction.cfm, does not exist yet, the ColdFusion Server sends an error.

At this point, this form has little value since it does not store any information in the database and does not enforce any business rules of Compass Travel. In the next exercise, you will develop the action page to enforce the business rules.


Developing code to validate data and enforce business rules

As described in Lesson 1, it is important to define the right data type for each column on the tables in the database. A fundamental concern, therefore, is ensuring that the captured data is suitable for the column definitions in the Trips table. This type of validation on a single field is often referred to as a single-field edit.

Compass Travel has other operating policies that involve evaluating the values from more than one field. These validations, referred to as cross-field edits, are usually more difficult to program. To assure that new trips are uniformly captured, Compass Travel has published cross-field validations and single-field edits in its Compass Travel business rules.

The following table lists the Compass Travel business rules for capturing and editing trip information. This table identifies which rules requiring single or cross-field editing.

Compass Travel new trip policy |  | Edit type
1 | All trips must be named. | single-field
2 | All trips must be accompanied by a full description. | single-field
3 | Each trip must be categorized by event type. Only valid event types (1-surfing, 2-mountain climbing, and so on) are permissible | single-field
4 | Trip locations are required. | single-field
5 | The maximum number of people permitted on the trip must be specified. | single-field
6 | The trip departure and return dates must be specified for each trip. All trip dates must be valid future dates. Departure date must precede return date. | single-field cross-field
7 | The trip’s price and base cost are required. Both values are positive numeric values. The trip price must have at least a 20% markup over base cost. | cross-field
8 | Any trip priced over $750 requires a deposit. | cross-field
9 | A trip leader must be identified. | single-field
10 | A photo must accompany all new trips. The photo image file must reside within the images directory of the Compass Travel website. | single-field


Ways to validate data

ColdFusion provides special tags to simply the process of enforcing business rules. Using ColdFusion, it is possible to enforce business rules in several places. For example, you can enforce some validation edits on the client. Other validation edits, you can enforce on the server after the data entry form is submitted. You will explore these options in the following sections.


Validating data using a server-side action page

The first approach you will take to enforce Compass Travel business rules is to develop an action page to validate the data collected on the data entry form. The action page receives a form variable for every field on the form that contains a value. You use the cfif tag to test the values of these fields to ensure that they adhere to Compass Travel business policy.


Using a cfif tag to enforce business rules

The cfif tag lets you create conditions that evaluate to either True or False. Therefore, to use the cfif tag to test whether a trip name was entered (business rule 1)on the Trip Edit form, you code the following cfif statement:

<cfif Form.tripName EQ "">
   <cfoutput> Trip Name cannot be blank. </cfoutput>
</cfif>

In the previous example, the cfif statement tests to see if the value of the form variable tripName is blank. If the trip name condition evaluates to True, ColdFusion sends "Trip name cannot be blank" to the browser.

Note: The keyword EQ is an operator used to test for equality. For more information about the cfif tag and its operators, see Developing ColdFusion MX Applications with CFML.


Evaluating check box and radio button variables

Business rule 8 in the Compass Travel new trip policy requires you to test the value of the depositRequired check box form variable. Check box and radio button variables are only passed to the action page when the user selects these options on the form. Therefore, an error occurs if the action page tries to use a variable that was not been passed.

To insure an error does not occur, you will use the IsDefined function in a cfif statement to determine whether the user selected the Deposit Required check box option on the form:

<cfif not IsDefined("Form.depositRequired")>
   <cfset form.depositRequired = "No">
</cfif>

The cfif statement and the IsDefined function evaluate the value of the form variable depositRequired to determine if a value exists. The statement not IsDefined returns True if the specified variable is not found and the cfset statement sets the form variable to No. No indicates a deposit is not required; Yes indicates a deposit is required.


Evaluating whether business rules fail

The purpose of the tripeditaction.cfm action page is to update the Compass Travel database, so it is important to make certain that all the business rules are passed successfully before the database insert is executed. Failure of any one of the rules negates the insert.

One approach to ensuring that the action page considers each business rule is to create a local variable with a cfset tag within the action page that tests to see if any of the business rules failed.

The cfset tag lets you manipulate the value of a variable. For example, the following pseudocode initializes a variable to a specific value and checks the value using the cfif statement:

<cfset isOk = "Yes">
if rule 1 fails then
<cfset isOK = "No"
...
if Rule n fails then
<cfset isOk = "No">
...
<cfif isOk = "Yes">
update the database
</cfif>

In the previous example, cfset initializes the local variable isOk to Yes. If any rule fails, the variable isOK is set to No. The code then tests if isOk equals Yes, before executing the SQL insert logic.

For more information about using the cfset and cfif tags and the IsDefined function, see Developing ColdFusion MX Applications with CFML or the CFML Reference.


Exercise: create an action page with server-side validation

In this exercise you build an action page (tripeditaction.cfm)to validate the data passed to the ColdFusion Server from the tripedit.cfm data entry page. You use the cfif and cfset tags to build edits that ensure the data passed is valid per the Compass Travel business rules. Additionally, you will use the ColdFusion IsDefined function to check to see if data was entered in the data entry form (tripedit.cfm).

To build trip edit action page and validate data passed:

  1. Open an editor and create a new page called tripeditaction.cfm in the my_app directory. The new page appears as follows:
    2. <html>
<head>
   <title>Untitled</title>
</head>

<body>
</body>
</html>
  2. To ensure that Compass Travel business rule 7 is met, insert the following code above the <html> tag on the tripeditaction.cfm page. For your convenience, business rule 7 is repeated.

    3. Business rule 7: The trip’s price and base cost are required. Both values are positive numeric values. The trip price must have at least a 20% markup over base cost.

    <!--- Base Cost is Required and must be Numeric --->
<cfif Form.baseCost EQ "" or IsNumeric(Form.baseCost) EQ False>
   <cfset IsOk = "No">
   <cfoutput>Base cost must be a number and cannot be blank.</cfoutput>
<cfelse>
   <!--- Price must be 20% greater than Base Cost --->
   <cfif Form.baseCost * 1.2 GT  #Form.price#>
      <cfset IsOk = "No">
      <cfoutput>Price must be marked up at least 20% above cost.</cfoutput><br>
   </cfif>
</cfif>

    Note: The code for business rule 7 uses ColdFusion cfif and cfelse conditional processing tags. The code inside the cfif tags only executes when the condition evaluates to True. To perform other actions when the condition evaluates to False, the cfelse tag is used. For more information about using conditional processing tags, see Developing ColdFusion MX Applications with CFML.
  3. Save the page.
  4. Use the following steps to test the code to see if it meets the objective of business rule 7:
    1. View the tripedit.cfm page in the browser.
    2. In the form, enter the number 500 in both the Price and Base cost fields.
    3. Click the Save button.

      4. The trip price error message displays: "Price must be marked up at least 20% above cost."

    4. Click the browser Back button to return to the tripedit.cfm page.
    5. To avoid the error, enter the number 800 in the Price field and click Save.
  5. Complete all the business rules using server-side validation. You must insert the code for each business rule above the <html> tag. As an example, see the tripeditaction1.cfm page in the solutions directory.

    6. Tip: You can either modify your new tripeditaction.cfm page to include the code necessary to meet all 10 business rules or you can copy the tripeditaction1.cfm page from the solutions directory to tripeditaction.cfm in the my_app directory.

  6. Test various combinations to make sure all the Compass Travel business rules are enforced by filling out the fields on the form and clicking save.

    7. Testing recommendations:

  7. Leave out required fields such as trip name or location.
  8. Enter in a non-numeric value in number of people such as one.
  9. Leave the entire form blank and click Save. The following messages appear:

    10. Trip name cannot be blank. A trip leader must be specified. Photo file name must be specified. The number of people must be a number and cannot be blank. Trip location cannot be blank. Base cost must be a number and cannot be blank. Price must be a number and cannot be blank.


Drawbacks of validating data on the server-side

Validating data on the server-side has two drawbacks. First, since the action page is used for validation, the form page is not in the browser context when the error is trapped. The user will, therefore, not get immediate feedback from the page where the data was entered. Second, because data capture occurs on the client and validation on the server, the number of round-trips to the server is increased. This can cause increased traffic on the network and the server. If the data is validated on the client, then only valid data is posted to the server and traffic is reduced.


Validating data on the client using ColdFusion form tags

An alternative approach to server-side editing is to use client-side scripting. Client-side scripting lets you validate the form data entered on the client prior to posting it to the server. CFML provides alternative versions of standard HTML form tags that provide advantages of client-side data validation.These data input tags include cfinput text, cfinput radio, cfinput checkbox, cfselect, and others.

Among the improvements over standard HTML tags, ColdFusion form tags offer the following attributes:

Attribute | Description
validate | The data type that the field tag validates against. Values include: integer, date, time, telephone, zipcode.
message | The error message displayed if validation fails.
range | The range of permissible values for this tag.
required | An indicator of whether data is required for the corresponding tag.


Examples of using the improved ColdFusion form tags

To use the improved form tags, you must replace the HTML form tag with the cfform tag. The following code snippets show the use of the improved ColdFusion form tags. The first code snippet shows how the duration field is validated on the server. The second code snippet shows how ColdFusion form tags simplify field validation on the client.


Server-side validation approach (no ColdFusion form tag)

The following code is on the client (tripedit.cfm page):

<input size=3 name=duration>
Code on the server (tripeditaction.cfm page):
<!--- Duration is Required and must be Numeric --->
<cfif Form.numberPeople EQ "" or IsNumeric(Form.numberPeople) EQ False>
   <cfset IsOk = "No">
   <cfoutput>The number of people must be a number and cannot be blank.
   </cfoutput>
</cfif>

Code
Explanation
<cfif Form.numberPeople EQ "" or
IsNumeric(Form.numberPeople) EQ False>
The cfif tag evaluates the value of the form variable numberPeople to determine if the user entered a value. The IsNumeric function checks whether the value entered on the form was a numeric value.


Client-side validation approach using ColdFusion form tag

The following code is on the client:

<cfinput  name="duration" message="Duration must be a number and cannot be blank."
validate="integer" required="Yes" size="3" maxlength="3">

Code
Explanation
<cfinput  name="duration"
message="Duration must be a number and
cannot be blank." validate="integer"
required="Yes" size="3" maxlength="3">
Use the cfinput tag to create the duration input entry field within a cfform. The validate attribute defines the field as an integer. The required attribute indicates that the field must have an entry. If the data is not entered or data entered is not an integer, the message attribute specifies that the message, "Duration must be...." appears.


Exercise: modify Trip Edit page to exploit ColdFusion form tags

In this exercise, you will use the ColdFusion form tags to move the validation of many business rules from the server to the client. To do this, you will change the HTML form tags in the tripedit.cfm page to ColdFusion form tags that validate these fields on the client side. Next, you will remove the unneeded server-side single-field validation code from tripeditaction.cfm page. Finally, you will test the form to ensure the client side validation is working correctly.

To exploit the ColdFusion form tags on the Trip Edit page:

  1. Open the tripedit.cfm in the my_app directory in your editor.
  2. Locate and change the <form> and </form> tags to <cfform> and </cfform>, respectively.
  3. Change the <input> tags to <cfinput> tags and <select> tags to <cfselect> tags. Note that the input type for the Submit button must remain a standard input rather than cfinput.
  4. For each ColdFusion form tag (cfinput, and cfselect), assign the appropriate values:

    Attribute value
    Description
    required
    Use this attribute for fields that must be filled out or selected.
    validate
    Use this attribute for fields that requires a specific data type for validation. Values include: integer, date, time, telephone, and zip code.
    message
    Use this attribute for fields that require an error message to be displayed if validation fails. The message reflects the text that describes the business rule.

    5. For example, the Trip Name field requires the following code:

    <cfinput maxlength = "50" size = "50" required = "Yes" name= "tripName"
message = "Trip name must not be blank">

    Tip: For additional help, review the completed code in the tripedit2.cfm within the solutions directory. For more details about using ColdFusion form tags and their attributes, see Developing ColdFusion MX Applications with CFML.
  5. In your editor, open the tripeditaction.cfm in the my_app directory and delete the code for the following single-field validation rule:
  6. Trip name is required.
  7. Trip leader is required.
  8. Photo file name is required.
  9. Number of people is required and must be numeric.
  10. Trip location is required.
  11. Base cost is required and must be numeric.
  12. Price is required and must be numeric.

    13. Tip: You can either remove the single-field validations yourself or use tripeditaction2.cfm file in the solutions directory. The file tripeditaction2.cfm in the solutions directory is a copy of tripeditaction with the single-field edits deleted. Copy tripeditaction2.cfm in the solutions directory to tripeditaction.cfm in the my_app directory.

  13. When you finish deleting the single-field validation rules, save the file.

    14. The modified tripeditaction.cfm page appears as follows:

    <!--- Action Page to edit and save Trip information for Compass Travel. --->
<!--- Single field edits have been removed in favor of client-side edits. --->
<!--- Make the passportRequired variable be No if it is not set
    (check box is empty) --->
<cfset isOk = "Yes">
<cfif not isdefined("Form.depositRequired")>
   <cfset form.depositRequired = "No">
</cfif>
<cfif Form.price GT 750 AND Form.depositRequired EQ "No">
   <cfset IsOk = "No">
   <cfoutput>Deposit is required for trips priced over $750.</cfoutput>
</cfif>
<cfif Form.basecost * 1.2 GT #Form.price#>
   <cfset IsOk = "No">
   <cfoutput>Price must be marked up at least 20% above cost.</cfoutput>
</cfif>
<cfif form.departureDate GT form.returnDate>
   <cfset isOk = "No">
   <cfoutput>Return date cannot precede departure date. Please
re-enter.</cfoutput>
</cfif><html>
<head>
<title>Trip Maintenance Confirmation</title>
</head>

<body>

<cfif isOk EQ "Yes">
   <h1>Trip Added</h1>
   <cfoutput>You have added #Form.TripName# to the trips database.
   </cfoutput>
</cfif>
</body>
</html>
  14. View the tripedit.cfm page in a browser and test the client- and server-side field validations by filling out the fields on the form and clicking Save.

    15. Testing recommendations:

  15. Omit required fields such as trip name or location.
  16. Make the departure date an invalid date like 12/32/2002.
  17. Enter a non-numeric value in number of people such as one.


Using cfselect tag to present valid event types

Currently the event types in tripedit.cfm are hard coded:

<!--- Field: eventType --->
<tr>
   <td valign="top">   Type of Event
   </td>
   <td>
<cfselect size="1" name="eventType" required="Yes" message="Type of
event must be selected.">
      <option value="1" selected>Surfing</option>
      <option value="2">Mountain Climbing</option>
      <option value="3">Mountain Biking</option>
      </cfselect>
   </td>
</tr>

As described in Lesson 1, the tutorial application design includes a database table that holds event types. The event type in the Trips table is an identifier used as a foreign key to the eventtypes table (which holds the actual event names). In the previous code, each option tag contains a value attribute and option text, such as Surfing. These values come from the eventtypes table so that they are not hard-coded. The eventtypes table column eventTypeID is used for the value attribute and the eventType for the literal value that is displayed in the select box. To retrieve the data from this table, you must include the following cfquery:

<cfquery name="GetEvents" datasource="CompassTravel">
   SELECT  eventType, eventTypeID
   FROM eventtypes
</cfquery>

To exploit the query in the option tags, you can replace the HTML select tag with cfselect.


The cfselect tag

The cfselect tag is an improved version of the HTML select tag. Like other ColdFusion form tags, the cfselect tag provides the required and message attributes that validate the data entered. Using the cfselect tag and the preceding cfquery, you can implement the eventType field data entry as follows:

<!--- Field: eventType --->
   <tr>
      <td valign="top">   Type of Event
      </td>
      <td>
      <cfselect size="1" name="eventType" required="Yes"
      message="Type of event must be selected.">
      <cfoutput query="GetEvents">
      <option value="#GetEvents.eventTypeID#">
                     #GetEvents.eventType#
      </option>
      </cfoutput>
      /cfselect>
      </td>
   </tr>


Exercise: use eventtypes table to load event types

Do the following steps to modify the Trip Edit page to display a list of event types from the eventtypes table and add validation.

To display a list of event types from the eventtypes table and add validation:

  1. View the tripedit.cfm page in a browser. Select the event types drop-down list. Notice that only three event types appear in the list.
  2. Open the tripedit.cfm in the my_app directory in your editor.
  3. Add the following code above the <html> tag:
    4. <cfquery name="GetEvents" datasource="CompassTravel">
   SELECT  eventType, eventTypeID
   FROM eventtypes
</cfquery>
  4. Replace the following eventtypes code lines:
    5. <cfselect size="1" name="eventType" required="Yes"
message="Type of event must be selected.">
   <option value="1" selected>Surfing</option>
   <option value="2">Mountain Climbing</option>
   <option value="3">Mountain Biking</option>
</cfselect>

with these lines:

<cfselect size="1" name="eventType" required="Yes"
message="Type of event must be selected.">
   <cfoutput query="GetEvents">
      <option value="#GetEvents.eventTypeID#">
         #GetEvents.eventType#
      </option>
   </cfoutput>
</cfselect>
  5. View the tripedit.cfm page in a browser. Select the event types drop-down list. Notice that all seven event types appear in the list.


Using other client-side script to reduce edits on the server

If you were interested in moving as much of the business rule logic to the client as possible, you might use other client-side scripting languages, such as JavaScript. By exploiting ColdFusion form tags, you moved most of the responsibility for the business rule checking from the server to the client. This section explains how to migrate cross-field business rules to the client using JavaScript.

Web browsers can execute scripts based on events triggered on the current page. One of the most popular scripting languages is JavaScript. ColdFusion Form tags include an onValidate attribute that lets you specify your own JavaScript function for custom validation.

The JavaScript form object, input object, and input object value are passed to the specified JavaScript function. The function returns True if validation succeeds and False otherwise. The onValidate and validate attributes are mutually exclusive.

Recall the Compass Travel New Trip business rule 6:

The trip departure and return dates must be specified for each trip.
All trip dates must be valid future dates. Departure date must precede return date.

The trip departure and return dates must be specified for each trip.

All trip dates must be valid future dates. Departure date must precede return date.

One reason this rule is a good candidate for a JavaScript function is that the test for a future date cannot be done using the ColdFusion form tags attributes such as validate and range. The following JavaScript function (isitFutureDate) tests whether a date is a valid future date.

function isitFutureDate(oForm, oTag, dateString) {
/*
   function isitFutureDate
   parameters: oForm, oTag, dateString
   returns: boolean

   oForm is the CFForm object.  All onvalidate calls pass this argument.
This function ignores it.
   oTag is the CFForm current tag object.  All onvalidate calls pass this
argument.  This function ignores it.
   dateString is the value of the current tag object. It should be a date passed
as a string in the following
   format: MM/DD/YYYY. This means that months and days require leading zeros!!

   Returns true if the date passed is greater than today's date
   Returns false if the date passed is NOT greater than todays
   date.
*/

   // Check to make sure the date is zero filled with 4 digit year and
   //therefore 10 characters long.
   if (dateString.length != 10)
      return false;
var now = new Date();
   var today = new Date(now.getYear(),now.getMonth(),now.getDate());
var testdate = new Date(dateString.substring(6,10),
               dateString.substring(0,2)-1,
               dateString.substring(3,5));
      if (testdate > now)
         return true;
      else
         return false;
}

Another reason that rule 6 requires JavaScript scripting is that it tests the values of more than one field in a single edit. You must ensure that the return date field is greater than departure date field. To do this, you add a JavaScript function to validate the trip date range entered, and specify the function on the onValidate attribute of the returnDate cfinput tag.

function validateTripDateRange(oForm, oTag, dateString)
{
   /*
   parameters: oForm, oTag, dateString
   returns: boolean

   oForm is the CFForm object.  All onvalidate calls pass this argument.
      This function ignores it.
   oTag is the CFForm current tag object.  All onvalidate calls pass this argument.
      This function ignores it.
   dateString is the value of the current tag object. It should be a date
      passed as a string in the following
   format: MM/DD/YYYY. This means that months and days require leading zeros!!

   Returns true if the date passed is a future date greater than the departure date
   Returns false if the date passed is NOT a future date greater than departure
      date.
*/

//Edit to make sure that Return date is Later than departure date.
   var returnDateString;

   //First check to see if the departure Date is a valid future date
   if (isitFutureDate(oForm, oTag, dateString) == false)
      return false;

   var departureDate = new Date(dateString.substring(6,10),
            dateString.substring(0,2)-1,
            dateString.substring(3,5));

   returnDateString = document.forms(0).item("returnDate").value;

   var returnDate = new Date(returnDateString.substring(6,10),
            returnDateString.substring(0,2)-1,
            returnDateString.substring(3,5));

   if (departureDate < returnDate)
      return true;
   else
      return false;
}

The important point about the preceding JavaScript is that you can use two functions, isitFutureDate and validateTripDateRange, to verify whether a date is in the future and the trip date range is valid, respectively.


Exercise: add JavaScript-based validation code

In this exercise you will modify the Trip Insert page to validate the departure and return dates using the JavaScript functions provided.

To validate the departure and return dates using JavaScript functions:

  1. Open tripedit.cfm in your editor and do one of the following:

    2. Copy example code provided Copy the tripsedit3.cfm file from the solutions directory and rename it to tripedit.cfm in the my_app subdirectory

    or

    Add JavaScript-based validation code to tripedit.cfm Follow these steps to modify the tripedit.cfm page:

    1. Copy and insert the text from the scriptvalidation.txt in the solutions directory right before the HTML body tag in tripedit.cfm.
    2. Modify the departureDate and returnDate input tags to include the onValidate attributes as follows:
      3.    <cfinput name="departureDate" size="10" validate="date"
onvalidate="isitFutureDate" message="Departure date must be a valid
future date (mm/dd/yyyy).">
   <cfinput size="10" name="returnDate" validate="date"
onvalidate="validateTripDateRange" message="Return date must be a valid
date greater than departure date (mm/dd/yyyy).">
    3. Save the tripedit.cfm in the my_app directory.
  2. Test this page by opening the tripedit.cfm page in your browser.
  3. Test the date validation by checking that each of the following tasks fail:
    1. Enter a date in the past for the departure date field; for example, 01/01/2000.
    2. Enter a departure date greater than the return date; for example, enter 02/01/2004 for the departure date, and 01/01/2004 for the return date.
  4. Test the date validation and ensure that the proper data succeeds; for example, enter 01/01/2004 for the departure date, and 01/14/2004 for the return date.
  5. Test for an invalid date by entering 12/32/2002 for the return date.

    6. You would expect the application to reject this date. It does not. This is because the validate attribute of a cfinput tag (returnDate in this example) is ignored when there is a JavaScript routine specified in the onValidate attribute. To correct this, you must write a test to validate the date using JavaScript (not addressed in this tutorial).


Validating the existence of the trip photo file

At this point, you have a more efficient application. The client is handling much of the validation of the Compass Travel new trip business rules. Except for the trip photo file, the server receives only valid data.

The trip photo file business rule does not fit nicely into this design, however. The last trip photo business rule has two parts:

  • A photo file name must accompany all new trips.
  • The photo image file must reside within the images directory of the Compass Travel website.

You used the required attribute for the photo cfinput tag to ensure that a file name is entered. Now you must make sure that the file exists in the right directory so the application can display it to customers.

Since browser clients are prohibited from doing standard file I/O (input/output) on the web server, the Trips Maintenance application will use server-side validation to ensure the existence of the photo file. You will add the business rule for the photo file to the tripeditaction.cfm page.

To check to see if a file exists, ColdFusion provides a FileExists function. The syntax of this function is:

   FileExists(absolute_path)

This function returns True if the file specified in the argument does exist; otherwise, it returns False. Assume that a data entry page has an input tag named "testFileName". If a user types in a valid file name, the action page snippet from the following example would display the message “The test file exists”:

<cfset fileLocation = "c:\inetpub\wwwroot\images\">
<cfif IsDefined("form.testFileName")>
      <cfif form.testFileName is not "">
   <!---Concatenate the File Location with the FileName passed in--->
      <cfset fileLocation = fileLocation  & form.testFileName>
         <cfif FileExists(fileLocation)>
            <cfoutput> The test file exists. </cfoutput>
         </cfif>
      </cfif>
</cfif>

Note: The trip photo images are stored in the following path relative to your web root directory: \cfdocs\getting_ started\photos. Therefore, if your web root is C:\inetpub\wwwroot, then the photos are stored in the C:\inetpub\wwwroot\cfdocs\getting_ started\photos directory.

For more information about the FileExists function, see CFML Reference.


Reviewing the code

The following table describes the code used to verify whether a file exists:

Code
Explanation
<cfif IsDefined("form.testFileName")>
The cfif tag checks to see if the form variable testFileName has been entered.
<cfset fileLocation = fileLocation  &
form.testFileName>
The ColdFusion & operator in the cfset tag combines the original value for fileLocation from the first source line
("c:\inetpub\wwwroot\images\") with the value of the testFileName form variable.
<cfif FileExists(fileLocation)>
FileExists checks to see if the file indicated by the fileLocation variable exists at the specified disk location.


Exercise: use FileExists function to verify the existence of photo file name

In this exercise, you will use the Cold Fusion FileExists function to ensure that the photo file name entered in the Trip Edit page exists in the location specified.

To verify that the photo file name exists:

  1. Open the tripeditaction.cfm in the my_app directory in your editor.
  2. In the tripeditaction.cfm page, do the following:
    1. Add logic to check that the user entered a valid photo file name by copying the code from the photofilecheck.txt file in the solutions directory pasting it immediately following the first <cfset isOk = "Yes"> statement.
    2. Verify that code you copied in step a is pointing to the correct photolocation path. The path is specified in the <cfset PhotoLocation = "C:..."> tag.

      3. For example, depending on your web server configuration, the photolocation path might be:

  3. For MS Windows systems:
    4.    <cfset PhotoLocation
   "C:\cfusionmx\wwwroot\CFDOCS\getting_started\Photos\">

or

   <cfset PhotoLocation =
   "C:\Inetpub\wwwroot\CFDOCS\getting_started\Photos\">
  4. For Linux or Solaris systems:
    5.    <cfset PhotoLocation =
   "/opt/coldfusionmx/wwwroot/cfdocs/getting_started/photos/">

or

   <cfset PhotoLocation =
   "/<webserverdocroot>/cfdocs/getting_started/photos/">
  5. Save the page and test it by opening the tripedit.cfm page in your browser.

    6. Testing recommendations:

    1. In the Trip Edit page entering valid information in all the required fields but the Photo File field.
    2. In the Photo File field, enter nowhere.jpg and click Save.

      3. The following error message appears: Trip photo does not exist.

    3. To avoid the error, replace the invalid photo file name in the Trip Edit page with somewhere.jpg and click Save.

      4. The following message appears: Trip added.


Summary

As described in this lesson, ColdFusion offers several alternatives to validating data. If you are familiar with standard page validation code, ColdFusion supports these development approaches. However, ColdFusion form tags simplify data validation. Additionally, you can use JavaScript with ColdFusion to execute client-side functions.


In the next lesson

Now that you are sure that your application can save valid data, in the next lesson, you will write code to add trips to the database. Additionally, you will add logic to update existing trip data in the Trips table.

Previous


Implementing the Browsing and Maintenance Database Functions

In this lesson, you will enhance the Compass Travel ColdFusion application by providing code to implement the navigation and maintenance database functions.

This lesson explains how to do the following tasks:

  • Use SQL SELECT to move to the first, last, next and previous rows in the trips table
  • Add code to the main application page to browse the trips table
  • Use SQL DELETE to delete rows in the trips table
  • Use cflocation to link the search facility built Preparing to Build the Sample Application to the main Trip Maintenance application page.
Next


ColdFusion tags and functions introduced in this lesson

The following table identifies the ColdFusion tag and structure that you use in this lesson to enhance the Trip Maintenance application:

Element | Type | Brief description
cflocation | Tag | Opens a ColdFusion page or HTML file.
URL | Structure | Structure to hold the variables within a URL.


Enhancing the Trip Maintenance application

In this lesson, you will make enhancements to the sample Trip Maintenance application that you created in previous lessons. In Validating Data to Enforce Business Rules, you added buttons to the Trip Detail page to browse, add, edit, delete or search for records in the database. In this lesson you will build the action pages that implement the actions for these buttons.


Page flow

You will combine the Trip Detail page and the search pages you built in the previous lessons with a maintenance action page and a navigation action page you will build in this lesson. In the final two lessons you will build a Trip Edit page to complete the trip maintenance facility. The following figure shows the flow of the finished Trip Maintenance application pages:

This is a picture of the feature being described.

Notice that the Trip Detail page is at the center of the Trip Maintenance application. Depending on the user action, the Trip Detail page navigates the records in the database or connects to the appropriate page to add, edit, delete, or search for records in the database.

In order for the application to process the user actions from the Trip Detail page, you must build the two action pages for the navigation and maintenance functions.


Navigation action page

This navigation action page determines which triprecord displays on the Trip Detail page after the user presses one of the navigation buttons. There is no HTML output displayed from this action page. Instead, this page uses dynamic SQL to identify the tripID that must display on the Trip Detail page. In this dynamic SQL statement the proper tripID is passed as a parameter to the URL then redirects it to the Trip Detail page.


Maintenance action page

The maintenance action page processes a user’s maintenance request from the Trip Detail page. The request can be any of the following actions:

  • Delete the currently displayed trip.
  • Launch the search facility.
  • Add a new trip (implemented in the previous two lessons).
  • Update the currently displayed trip (implemented in the previous two lessons).


Application development steps

You will review or participate in the following application construction steps:

Steps | Description
1 | Build the navigation action page to navigate and display the proper trip record.
2 | Build the maintenance action page to process the user’s selection on the Trip Detail page.


Using dynamic SQL to browse (navigate) the Trips table

The tripID uniquely identifies a trip in the Trips table. In Lesson 3, you displayed the Trip Detail page for a trip by passing the ID as a parameter of the URL launching the detail page. Therefore, you would navigate to the following URL to display the detail information for a trip with the ID of 20:

http://localhost/cfdocs/getting_started/my_app/tripdetail.cfm?ID=20

The main objective of the Navigation Action page (navigationaction.cfm) is to navigate to the Trip Detail page with a proper URL identifying the correct tripID based on the navigation button clicked. Unfortunately, because trips are added and later deleted, trips might not be ordered sequentially by ID. There can be missing IDs where trips were deleted. Therefore, if the current trip ID is 1 and the user clicks the next navigation button, it will not navigate to 2.

In order to ensure that the proper tripID is retrieved, you must create a query to the database to find out what the next (or previous, first, or last) ID is based on the current tripID. The navigation action page uses dynamic SQL to build a query to find the appropriate ID to use.

In Lesson 2, you used ColdFusion string manipulation to construct the proper SQL SELECT WHERE clause. In this lesson, you will use a similar approach to build the WHERE clause for navigation. Additionally, it is necessary to use the proper ORDER BY clause to select the correct trip row.

For example, if the current tripID equals 6, the following table identifies the proper SQL statement based on the navigation button clicked by the user:

Navigation
button
SQL statement to navigate to
correct trip ID

SQL statement description
First Row
SELECT tripID FROM trips
ORDER BY tripID
Returns the list of all tripIDs in ascending (1,2,3...) order.
Previous Row
SELECT tripID FROM trips
WHERE tripID < 6
ORDER BY tripID DESC
Returns the list of all tripIDs less than 6 in descending (5,4,3...) order.
Next Row
SELECT tripID FROM trips
WHERE tripID > 6
ORDER BY tripID
Returns the list of all tripIDs greater than 6 in ascending (7,8,9...) order.
Last Row
SELECT tripID FROM trips
ORDER BY tripID DESC
Returns the list of all tripIDs in descending (99,98,97...) order.


Limiting the number of result rows

Each of the SQL statements in the previous table return a result set of trips rows. The result set can range from zero to any number of rows. The navigation action page must limit the result set count to 1, since only the initial row in the result set is needed for the Trip Detail page display.

ColdFusion provides the maxRows attribute on the cfquery tag for this purpose. This attribute limits the number of result rows returned from the database. To show only a single row at a time in the Trip Detail page, set maxRows to 1.


The navigation action page

To properly build the SQL SELECT statement for previous and next row navigation, you must know the current tripID. This is the reason for using the hidden input tag RecordID on the Trip Detail page. You can then use the form variable #Form.RecordID# in the navigation action page for building the proper test in the WHERE clause of the SQL SELECT statement. The following code (from the navigationaction.cfm) processes the navigation button requests on the Trip Detail page:

<!---         NAVIGATION BUTTONS          --->

<cfquery name="TripQuery" dataSource="compasstravel" maxRows=1>

   SELECT tripID FROM trips

   <cfif IsDefined("Form.btnPrev.X")>
      WHERE tripID < #Form.RecordID#
      ORDER BY tripID DESC

   <cfelseif IsDefined("Form.btnNext.X")>
      WHERE tripID > #Form.RecordID#
      ORDER BY tripID

   <cfelseif IsDefined("Form.btnFirst.X")>
      ORDER BY tripID

   <cfelseif IsDefined("Form.btnLast.X")>
      ORDER BY tripID DESC

   </cfif>

</cfquery>
   <cfif TripQuery.RecordCount is 1>

   <cflocation url="tripdetail.cfm?ID=#TripQuery.tripID#">

<cfelese>
   <cflocation url="tripdetail.cfm?ID=#Form.RecordID#">

</cfif>


Reviewing the code

The following table describes the code used to process the navigation button requests:

Code
Explanation
<cfquery
   name="TripQuery"
   dataSource="compasstravel"
   maxRows=1>
The cfquery tag identifies that a query named "TripQuery" will be executed against the "CompassTravel" data source. The number of rows returned cannot exceed 1 (maxRows=1).
SELECT tripID FROM trips
The SQL SELECT statement will always start with "SELECT tripID FROM trips".
<cfif IsDefined("Form.btnPrev.X")>
   WHERE tripID < #Form.RecordID#
   ORDER BY tripID DESC

<cfelseif IsDefined("Form.btnNext.X")>
   WHERE tripID > #Form.RecordID#
   ORDER BY tripID

<cfelseif IsDefined("Form.btnFirst.X")>
   ORDER BY tripID

<cfelseif IsDefined("Form.btnLast.X")>
   WHERE tripID > #Form.RecordID#
   ORDER BY tripID DESC

</cfif>

</cfquery>
The cfif tag checks if the user pressed a navigation button on the browse page. The X property is checked since the buttons on the detail page use image type HTML input tags. The X property is a mouse offset that gets sent when you click a graphic button.
The WHERE and ORDER BY clauses will vary depending on the navigation button clicked by the user.
<cfif TripQuery.RecordCount is 1>
<cflocation
url="tripdetail.cfm?RecordID=#TripQuery.tripID#">
<cfelse>
<cflocation
url="tripdetail.cfm?RecordID=#Form.RecordID#">
</cfif>
The cfif tag checks if the query returned a row to display. If it did, use that tripID to form a URL to navigate to using the cflocation tag. If the query returned no rows, navigate back to the detail page with current record id passed in the hidden form variable RecordID.


Exercise: implement trip record browsing (navigation)

Follow these steps to implement the trip record browsing functionality (navigation buttons) on the Trip Detail page. In this exercise, you will use the supplied navigation action page to implement and test the navigation buttons on the Trip Detail page.

To implement the trip record browsing functionality:

  1. Copy the navigationaction.cfm file from the solutions subdirectory in the getting_started directory to the my_app directory.
  2. View the tripdetail.cfm page from the my_app directory in a browser and test the navigation buttons as follows:
    1. Click Next Row.

      2. The Trip Detail page shows information about the second trip.

    2. Click Previous Row.

      3. The Trip Detail page shows information about the first trip.

    3. Click Last Row.

      4. The Trip Detail page shows information about the last trip.

    4. Click First Row.

      5. The Trip Detail page shows information about the first trip.


Building the maintenance action page

The maintenance action page (maintenanceaction.cfm) handles the user’s maintenance requests. The delete request is handled directly within the maintenance action page. The search request is accomplished by linking the Trip Search page. The maintenance action page navigates to another page for data capture for add and edit requests.

You will build the tripedit.cfm page to capture the information for add and edit requests in the next lesson. The following table identifies the button clicked on the Trip Detail page with the action taken in the maintenance action page:

Button | Action taken in maintenaceaction.cfm
Search | Navigate to tripsearch.cfm built in Lesson 4.
Delete | Execute SQL DELETE statement for current tripID.
Edit | Navigate to tripedit.cfm with ID parameter in URL set to current tripID.
Add | Navigate to tripedit.cfm with ID parameter in URL set to blank.


Maintenance action page code

ColdFusion creates a variable only for the button that the user clicked. Therefore, the IsDefined function is used to test which action to take. The following code is an excerpt from the maintenanceaction.cfm page that tests which action to take:

<cfif IsDefined("Form.btnSearch")>
...
<cfelseif IsDefined("Form.btnDelete")>
...
<cfelseif IsDefined("Form.btnEdit")>
...
<cfelseif IsDefined("Form.btnAdd")>
...
</cfif>

The first two buttons are the easiest to handle because they do not require building any new pages. Therefore, you will implement the functionality for the Search and Delete buttons first.


Linking the Trip Detail page to the Trip Search page

The ColdFusion cflocation tag navigates from the current page to a target HTML or CFML page. The URL attribute contains the name of the target page and any arguments. The code to navigate to the search page (tripsearch.cfm) follows:

<cflocation url="tripsearch.cfm">


Deleting the current trip record shown on the Trip Detail page

Before you can write the code to delete a trip, you must understand the underlying SQL statement to delete rows from the trips table.


SQL DELETE Statement

The SQL DELETE statement removes existing rows in a relational table. The format of the DELETE statement is as follows:

DELETE FROM table_name WHERE column_name = some_value

Consider a database table named Clients that holds information about people with the following rows:

LastName | FirstName | Address | City
Jones | Tom | 50 Main St | New York
Adamson | Anita | 521 Beacon St | Boston
Green | Peter | 1 Broadway | New York

To delete everyone from New York from the table, use the following statement:

DELETE FROM Clients WHERE City = 'New York'

After the database management system processed the preceding statement, the table would contain the following row only:

LastName | FirstName | Address | City
Adamson | Anita | 521 Beacon St | Boston

To ensure that the Trip Maintenance application deletes only the proper trip, you must use the unique tripID key when issuing the SQL DELETE. The RecordID field holds the tripID. Therefore, using the hidden RecordID input tag from the Trip Detail page, the following SQL statement deletes a row from the Trips table reads:

DELETE FROM trips WHERE tripID = #Form.RecordID#


Exercise: handle search and delete in maintenance action page

In this exercise, you will link the search function developed in Validating Data to Enforce Business Rules to the main page. Further, you will provide code to support the trip delete function. Then you will test this functionality by deleting a trip, then searching for it to ensure it was deleted successfully.

Follow these steps to create the maintenance action page that implements the search and delete functionality.

To create the maintenance action page:

  1. In your editor, create a CFM page.
  2. Delete any default lines of code if your editor automatically adds them.
  3. To handle the Search and Delete buttons from the Trip Detail page, enter the following code:
    4. <!---         SEARCH BUTTON            --->
<cfif IsDefined("Form.btnSearch")>
      <cflocation url="tripsearch.cfm">
<!---         DELETE BUTTON          --->
<cfelseif IsDefined("Form.btnDelete")>
   <cfquery name="DeleteRecord" dataSource="CompassTravel">
      DELETE FROM trips WHERE tripID = #Form.RecordID#
   </cfquery>
   <cflocation url="tripdetail.cfm">
</cfif>
  4. Save the page as maintenanceaction.cfm in the my_app directory.
  5. View the tripdetail.cfm page in a browser.

    6. The current trip is Nepal. Notice that the destination for Nepal Summit Challenge trip is Imji Himal, Nepal.

  6. Click Search.

    7. The Trip Search page appears.

  7. In the Trip Search page, select begins with in the selection box for Trip Location. Then enter Imji in the trip location value field.

    8. The following figure shows the search form looks:

    This is a picture of the feature being described.

  8. Click Search. Verify that only a single trip is found whose location begins with Imji.
  9. To return to the Trip Detail page for this trip, click the hyperlink for Imji.
  10. In the Trip Detail page, click Delete to remove this record from the Trip database file.
  11. Verify that the trip record was removed from the Trips database by repeating the search in step 7.


Summary

In this lesson, you converted the Trip Detail page from the search result display into a trip browser by using cfquery with SQL SELECT. The browser enables users to navigate sequentially through the Trips table. You also limited the result set of the dynamic query using the MaxRows attribute of the cfquery tag.

By implementing the Maintenance Action page, you enabled users to take action on the current trip. You used the ColdFusion cflocation tag to link the search page to the Trip Detail page. Additionally, you used cfquery and SQL DELETE to delete the current trip.


In the next lesson

You have implemented two of the four maintenance buttons on the Trip Detail page. In the next lesson, you will implement the Add and Edit buttons. Because these functions require user input, you will build a new page, tripedit.cfm, to capture this information. The user input must be validated against the Compass Travel business rules before the data is saved to the database. Therefore, in the next lesson, you also will implement the business rule validation. In the final lesson, you will add the database update logic.

Previous


Adding and Updating SQL Data

In this lesson, you will complete the Compass Travel Trip Maintenance application. The exercises will guide you through the steps of adding the database update logic to add new trip offerings and update existing trips in the Compass Travel database.

This lesson explains how to do the following tasks:

  • Modify the Trip Edit page to link the add and update functions to the main application page.
  • Write code to insert new trips using SQL.
  • Write code to insert new trips without using SQL.
  • Write code to update several records in the Trips table.
Next


ColdFusion tags and functions introduced in this lesson

The following table identifies the ColdFusion tags and functions that you use in this lesson to enhance the ColdFusion application:

Element | Type | Description
cfinsert | Tag | Inserts records in a JDBC data source.
cfupdate | Tag | Updates a records in a JDBC data source.


Completing the Trip Maintenance application

In Implementing the Browsing and Maintenance Database Functions, you created the tripeditaction.cfm page to contain server side edits for the trip edit data entry form. In this final lesson, you will complete the tripeditaction.cfm page. To complete the action page, you will write code to do these tasks:

  • Add trips to the Compass Travel database using the cfquery tag and the SQL INSERT statement.
  • Add trips to the Compass Travel database using the cfinsert tag.
  • Update the current trip using the cfupdate tag.
  • Link the current trip to be updated or added by the tripeditaction.cfm with the tripedit.cfm page.

In addition to completing the Trip Maintenance application, you will develop a ColdFusion page to update all the prices in the database using the cfquery tag and the SQL UPDATE statement.


Writing code to save new trips to the database

In Implementing the Browsing and Maintenance Database Functions, you built a Trip Edit page to collect the data. Now you can modify the Trip Edit action page to insert the data into the database. There are two approaches to inserting data into a SQL database:

  • Build a SQL INSERT statement and execute it using the cfquery tag.
  • Use the ColdFusion cfinsert tag. This approach eliminates the need for you to learn SQL syntax.


Adding data using SQL INSERT with cfquery approach

In previous lessons, you used the SQL SELECT statement to retrieve data and the SQL DELETE statement to delete data from the Trips table in the Compass Travel database. To add new trips to the database using SQL, you must understand the syntax of the SQL INSERT statement.

The SQL INSERT statement inserts new rows into a relational table. The format of the INSERT statement is as follows:

INSERT INTO table_name
VALUES (value1, value2,....)

The database table named Clients contains information about people in the following rows:

LastName | FirstName | Address | City
Tom | Jones | 12 State St | Boston
Peter | Green | 1 Broadway | New York

After the following SQL statement executes:

INSERT INTO Clients
VALUES ('Smith', 'Kaleigh', '14 Greenway', 'Windham')

the table contains the following rows:

LastName | FirstName | Address | City
Tom | Jones | 12 State St | Boston
Peter | Green | 1 Broadway | New York
Smith | Kaleigh | 14 Greenway | Windham

Notice that the values inserted in the table were surrounded by single quotation marks. In SQL, you must surround any text or date values with single quotation marks but numeric values are not.

Alternatively, you can specify the columns for which you want to insert data. This approach lets you insert data to some columns while omitting others. The syntax for this approach is as follows:

INSERT INTO table_name (column1, column2,...)
VALUES (value1, value2,....)

For example, the syntax to add Kaleigh Smith of Windham, with the address unknown, you use the named column approach:

INSERT INTO Clients (LastName, FirstName, City)
VALUES ('Smith', 'Kaleigh', 'Windham')

You used the cfquery tag to execute SQL from ColdFusion. The cfquery tag passes SQL statements to your data source. As described in Chapter 4, a data source stores information about how to connect to an indicated data provider, such as a relational database management system. The data source you established in Chapter 4 stored information on how to access the Compass Travel database. The data source name was called “CompassTravel”.


Exercise: insert trip data using SQL INSERT and cfquery

In this exercise you will add code to pass the data entered on the Trip Maintenance collection form and insert into the Compass Travel database. To do this, you will be modifying the trip insert action page to use the SQL INSERT statement and the ColdFusion cfquery tag.

To add data using SQL INSERT and cfquery:

  1. Open tripeditaction.cfm in the my_app directory in your editor.
  2. Locate the <cfif isOk EQ "Yes"> tag near the end of the file. After the <H1> Trip Added</H1> line, add the following code to insert the data from the Form variables into the Trips table:

    3. Tip: To save time, you can copy this code from the tripsinsertquery.txt file (for Windows users) or from tripinsertqueryunix.txt (for UNIX users) in the solutions directory.

    For
    Code
    Windows users, using MS Access
    <!--- Insert the new  trip record  into the Compass
   Travel Database --->
<cfquery name="AddTrip" datasource="compasstravel">
   INSERT INTO Trips (tripName, eventType, tripDescription,
      tripLocation,departureDate, returnDate, price, tripLeader,
      photo, baseCost, numberPeople, depositRequired)
   VALUES ( '#Form.tripName#', #Form.eventType#,
      '#Form.tripDescription#',
      '#Form.tripLocation#','#Form.departureDate#',
      '#Form.returnDate#',
      #Form.price#, '#Form.tripLeader#', '#Form.photo#',
      #Form.baseCost#, #Form.numberPeople#, '#Form.depositRequired#'
</cfquery>
    UNIX users, using Pointbase
    <!--- Insert the new  trip record  into the
   Compass Travel Database --->
<!--- Use local variables to convert dates to JDBC format
   (yyyy-mm-dd) from input format (mm/dd/yyyy) --->
<cfset JDBCdepartureDate = #Right(Form.departureDate,4)#
   & "-" & #Left(Form.departureDate,2)# & "-"
   & #Mid(Form.departureDate,4,2)#>
<cfset JDBCreturnDate = #Right(Form.returnDate,4)# & "-"
   & #Left(Form.returnDate,2)# & "-"
   & #Mid(Form.returnDate,4,2)#>
<cfquery name="AddTrip" datasource="CompassTravel">
   INSERT INTO Trips (tripName, eventType,
   tripDescription, tripLocation,
      departureDate, returnDate, price, tripLeader, photo,
      baseCost, numberPeople,   depositRequired)
  VALUES ( '#Form.tripName#', #Form.eventType#,
'#Form.tripDescription#',
      '#Form.tripLocation#', Date'#JDBCdepartureDate#',
      Date'#JDBCreturnDate#',
      #Form.price#,'#Form.tripLeader#', '#Form.photo#',
      #Form.baseCost#, #Form.numberPeople#, '#Form.depositRequired#')
</cfquery>

  3. Save the page and test it by opening the tripedit.cfm in your browser.
  4. In the tripedit.cfm page, fill in the fields with the values in the following figure, then click Save:

    5. This is a picture of the feature being described.

    After the new trip is written to the database, the following message appears: Trip is added.

  5. To verify that the save worked, open tripsearch.cfm in the my_app directory in your browser.
  6. In the Trip Search page, enter Begins With Nor in the Trip Location criterion value in the Search page as in the following figure:

    7. This is a picture of the feature being described.

  7. Click Search.

    8. The TripResults page appears:

    This is a picture of the feature being described.

  8. Click the link to the NH White Mountains to display the details of the trip you just added. Verify that all the fields were saved correctly.

    9. The following page appears:

    This is a picture of the feature being described.

  9. Click the Delete button to delete this record so that you can reuse the steps 4-8 of this exercise in the next exercise.


Reviewing the code

The following table describes the SQL INSERT and cfquery code used to add data:

Code
Explanation
<cfquery name="AddTrip"
datasource="CompassTravel">
Using the datasource attribute, cfquery connects to the data source CompassTravel and returns a result set identified by the name attribute.
INSERT INTO Trips (TripName,
EventType, tripDescription,
tripLocation, departureDate,
returnDate, price,
tripLeader,photo,
baseCost, numberPeople,
depositRequired)
  VALUES ( '#Form.TripName#',
#Form.EventType#,
'#Form.tripDescription#',
'#Form.tripLocation#',
'#Form.departureDate#',
'#Form.returnDate#', #Form.price#,
'#Form.tripLeader#',
'#Form.photo#',
#Form.baseCost#,
Form.numberPeople#,
'#Form.depositRequired#)
The SQL INSERT statement identifies that the data are to be inserted into the Trips table. The table column names are cited in a comma separated list surrounded by parenthesis (TripName, EventType....) after the table name Trips.
The VALUES keyword indicates the list of values that are inserted into the columns in the same order as the columns are specified earlier in the statement.
The values refer to form variables passed from the data entry form to the action page. The variables are surrounded by pound signs; for example, #Form.baseCost#. Additionally, note that if the column data type is a string data type, then the values are surrounded by single quotation marks; for example: '#Form.TripName#'.

For more information about adding data to a database using SQL and cfquery, see Developing ColdFusion MX Applications with CFML. For more information about SQL, consult any SQL primer.


Adding data using the simpler, cfinsert approach

For those who would prefer not to have to remember SQL syntax to add information to SQL databases, ColdFusion simplifies the coding for inserting SQL rows through the use of the cfinsert tag. As you might expect, the cfinsert tag has datasource and tablename attributes to specify where the data is inserted. The tag also has a formfields attribute to identify which fields to insert. Formfields is a comma-separated list of form fields to insert. If this attribute is not specified, all fields in the form are included in the operation. The following example uses the cfinsert with these attributes:

<cfinsert datasource="CompassTravel" tablename="Trips"
formfields="tripName, eventType, tripDescription, tripLocation, departureDate,
returnDate, price, tripLeader, photo, baseCost, numberPeople,
depositRequired">

The cfinsert tag used in the previous code snippet uses the following attributes:

Attribute | Description
datasource | The data source name associated with the database where the data is inserted.
tablename | The name of the SQL table within the database where the data are inserted.
formfields | A comma-separated list of form fields to insert.


Exercise: insert trip data using cfinsert

In this exercise, you change the approach the action page uses to insert the data into the database. You will replace the SQL INSERT statement with the cfinsert tag.

To add data using cfinsert:

  1. Open tripeditaction.cfm from the my_app directory in your editor and do the following:
    1. Remove the entire AddTrip cfquery that you added in the last exercise (from the beginning <cfquery name ="AddTrip" datasource="CompassTravel"> tag to the </cfquery> end tag).
    2. Add the following cfinsert tag to insert data into the trips table in the same location as the code that you just deleted:
      3.     <cfinsert datasource="CompassTravel" tablename="TRIPS">
  2. Save the page and test it by opening the tripedit.cfm page in your browser.
  3. Follow steps 4 through 9 in the previous exercise to verify this approach to inserting new trips.

For more information about adding data to a database using the cfinsert tag, see Developing ColdFusion MX Applications with CFML.


Updating a SQL row using cfupdate

To update an existing SQL row, ColdFusion offers a simple approach for updating SQL rows through the use of the cfupdate tag. Like cfinsert, the cfupdate tag has datasource and tablename attributes to specify where the data is to be inserted. The tag also has a formfields attribute to identify which fields are to be inserted. Formfields is a comma-separated list of form fields to insert. If this attribute is not specified, all fields in the form are included in the operation.

All the fields of the tripedit.cfm page have corresponding columns in the Trips table, so you can omit the FormFields attribute for both the cfinsert and cfupdate tags. If the tripID form field is passed from the TripEdit page the cfupdate tag is used otherwise the cfinsert tag is executed. The following example uses the cfupdate and cfinsert without the FormFields attribute:

<cfif not isdefined("form.tripID")>
   <cfinsert datasource="CompassTravel" tablename="Trips">
      <cflocation url="tripdetail.cfm">
   <cfelse>
   <cfupdate datasource="CompassTravel" tablename="Trips">
      <cflocation url="tripdetail.cfm?ID=#Form.tripID#">
</cfif>


Reviewing the code

The following tables describes the cfinsert and cfupdate code:

Code
Explanation
<cfif not isdefined("form.tripID")>
   <cfinsert datasource="CompassTravel"
   tablename="Trips">
      <cflocation url="tripdetail.cfm">
<cfelse>
<cfupdate datasource="CompassTravel"
   tablename="Trips">
<cflocation url="tripdetail.cfm?ID=#Form.tripID#">
</cfif>
The ColdFusion function IsDefined determines whether the hidden field tripID was passed to the action page from tripedit.cfm. If there is a current trip, the isDefined function returns True. When there is no current trip, the cfif statement is True. When the cfif statement is True , the cfinsert tag executes and the main page displays with the updated trip. If the cfif statement evaluates to False, the cfinsert statement executes and the first trip displays in the main page.


Exercise: update trip data using cfupdate

In this exercise, you will add the code to update the trip data into the database. You will add the cfupdate tag to the tripeditaction.cfm page.

To update the database using cfupdate:

  1. In an editor, open tripeditaction3.cfm from the solutions directory.
  2. Review the code to update the database (the last 12 lines of code).
  3. Verify that the correct photolocation path is specified. This path is specified in the <cfset PhotoLocation = "C:..."> tag.

    4. For example, depending on your web server configuration, the photolocation path might be:

  4. For MS Windows systems:
    5.    <cfset PhotoLocation
      "C:\cfusionmx\wwwroot\CFDOCS\getting_started\Photos\">

or

   <cfset PhotoLocation =
      "C:\Inetpub\wwwroot\CFDOCS\getting_started\Photos\">
  5. For Linux or Solaris systems:
    6.    <cfset PhotoLocation = "/opt/coldfusionmx/wwwroot/cfdocs/
      getting_started/photos/">

or

   <cfset PhotoLocation = "/<webserverdocroot>/cfdocs/
      getting_started/photos/">
  6. Save the file as tripeditaction.cfm in the my_app directory.

For more information about adding data to a database using the cfupdate tag, see Developing ColdFusion MX Applications with CFML.

Now that you have built the data entry form adding new and updating existing trips, you will add the logic to link it to the main trip page to test the update logic.


Linking the Trip Edit page to the main page

As discussed in Lesson 4, the action page for the maintenance buttons on the main page is maintenanceaction.cfm. You previously added code for the Search and Delete buttons. In the next exercise you will insert the code to call tripedit.cfm from maintenance.cfm as follows:

<!---         EDIT BUTTON          --->
<cfelseif IsDefined("Form.btnEdit")>
   <cflocation url="tripedit.cfm?ID=#Form.RecordID#">
<!---         ADD BUTTON          --->
<cfelseif IsDefined("Form.btnAdd")>
   <cflocation url="tripedit.cfm">
</cfif>

Notice that when the user clicks the Add button, the maintenanceaction.cfm navigates to tripedit.cfm passing no arguments. Conversely, when the user clicks the Edit button, the Trip Edit page passes the current record id. The Trip Edit page must handle both cases. When a RecordID is passed on the URL, tripedit.cfm must query the database and fill the form with the data for the corresponding trip. The following code properly initializes the trip edit form:

<cfif IsDefined("URL.ID")>
   <cfquery name="TripQuery" datasource="CompassTravel" maxrows="1">
      SELECT tripName, eventType, tripDescription, tripLocation,
      departureDate, returnDate, price, tripLeader, photo, baseCost,
numberPeople, depositRequired, tripID
      FROM trips
   <cfif IsDefined("URL.ID")>
      WHERE tripID = #ID#
         </cfif>
   </cfquery>
<!-- Set the local variables -->
   <cfset tripName = '#TripQuery.tripName#'>
   <cfset eventType = #TripQuery.eventType#>
   <cfset tripDescription = '#TripQuery.tripDescription#'>
   <cfset tripLocation = '#TripQuery.tripLocation#'>
   <cfset departureDate = DateFormat(#TripQuery.departureDate#,"mm/dd/yyyy")>
   <cfset returnDate = DateFormat(#TripQuery.returnDate#,"mm/dd/yyyy")>
   <cfset price = #TripQuery.price#>
   <cfset tripLeader = '#TripQuery.tripLeader#'>
   <cfset photo = '#TripQuery.photo#'>
   <cfset baseCost = #TripQuery.baseCost#>
   <cfset numberPeople = #TripQuery.numberPeople#>
   <cfset depositRequired = '#TripQuery.depositRequired#'>
   <cfelse>
   <cfset tripName = ''>
   <cfset eventType = ''>
   <cfset tripDescription = ''>
   <cfset eventTypeIdentifier = #TripQuery.eventType#>
   <cfset tripLocation = ''>
   <cfset departureDate =  ''>
   <cfset returnDate = ''>
   <cfset price = ''>
   <cfset tripLeader = ''>
   <cfset photo = ''>
   <cfset baseCost = ''>
   <cfset numberPeople = ''>
   <cfset depositRequired = ''>
</cfif>


Reviewing the code

The following table describes the code used to properly initialize the trip edit form:

Code
Explanation
<cfif IsDefined("URL.ID")>
<cfquery name="TripQuery" datasource="CompassTravel"
maxrows="1">
   SELECT tripName, eventType, tripDescription,
tripLocation, departureDate, returnDate, price,
tripLeader, photo, baseCost, numberPeople,
depositRequired, tripID
   FROM trips
   <cfif IsDefined("URL.ID")>
      WHERE tripID = #ID#
   </cfif>
</cfquery>
      <!-- Set the local variables -->
<cfset tripName = '#TripQuery.tripName#'>
<cfset eventType = #TripQuery.eventType#>
      <cfset tripDescription =
TripQuery.tripDescription#'>
<cfset tripLocation = '#TripQuery.tripLocation#'>
<cfset departureDate =
DateFormat(#TripQuery.departureDate#,"mm/dd/yyyy")>
<cfset returnDate =
DateFormat(#TripQuery.returnDate#,"mm/dd/yyyy")>
...
<cfelse>
<cfset tripName = ''>
<cfset eventType = ''>
...
</cfif>
The ColdFusion function IsDefined determines whether an ID argument was passed as part of the invoking URL.
The ID argument is passed when TripEdit is invoked when the Edit button is clicked on the main page.
When an ID is passed, it is used in the WHERE clause of the SQL SELECT statement to retrieve the information about the current trip. The program then instantiates local variables from the results of the SQL query.
ColdFusion DateFormat function formats the date fields.
If TripEdit is called to add a new trip, then there is no ID passed as a URL argument. In this case, the local variables are instantiated to blank.


Exercise: linking the Add and Edit buttons

In this exercise you will link the Add and Edit buttons on the Trip Detail page with the Trip Edit page.

To link the add and update buttons on the Trip Detail page:

  1. Open maintenanceaction.cfm in the my_app directory in your editor.
  2. Locate the </cfif> tag at the end of the file.
  3. Insert the following code just before the last line:
    4. <!---         EDIT BUTTON          --->
   <cfelseif IsDefined("Form.btnEdit")>
      <cflocation url="tripedit.cfm?ID=#Form.RecordID#">
<!---         ADD BUTTON          --->
   <cfelseif IsDefined("Form.btnAdd")>
      <cflocation url="tripedit.cfm">
   </cfif>
  4. Save maintenanceaction.cfm.
  5. Open tripedit4.cfm in the solutions directory in your editor.
  6. Open the file initvariables.txt from the solutions directory.
  7. Copy the contents of the initvariables.txt and paste it before the <HTML> tag in the tripedit4.cfm page.
  8. Save the file as tripedit.cfm in the my_app directory.
  9. Test update logic by opening the tripdetail.cfm page in your browser and doing the following tasks:
    1. Click the Edit button.
    2. Double the price of the current trip.
    3. Click Save.

The ColdFusion cfupdate works well for updating a single record. To update several records in a single query, you must use the SQL UPDATE statement in conjuction with cfquery.


SQL Update

The SQL UPDATE statement updates or changes rows in a relational table. The syntax of the UPDATE statement is as follows:

UPDATE table_name SET column_name = new_value
WHERE column_name = some_value

Consider a database table named Clients that contains information about people in the following rows:

PersonID | LastName | FirstName | Age
1 | Green | Tom | 12
2 | Wall | Peter | 42
3 | Madigan | Jess | 20

After the following SQL statement executes:

UPDATE Clients SET LastName = ’Pitt’
WHERE ID = 3

the table contains the following rows:

PersonID | LastName | FirstName | Age
1 | Green | Tom | 12
2 | Wall | Peter | 42
3 | Pitt | Jess | 20


Update several rows

The UPDATE statement updates all rows that meet the criteria found in the WHERE clause. If there is no WHERE clause, every row of the table is updated. After the following SQL statement executes:

UPDATE Clients SET Age = Age + 1
WHERE ID = 3

the table contains the following rows:

PersonID | LastName | FirstName | Age
1 | Tom | Green | 12
2 | Peter | Green | 42
3 | Pitt | Jess | 21


Updating multiple records

The cfupdate statement works well when you want to update the current record within a cfquery. Alternatively, you can update several rows within a table by issuing a single query using cfquery and the SQL UPDATE statement. For example, if the base cost of all trips increased by 5%, you could issue the following query:

<!-- Routine to increase trip base Cost by 5% -->
<cfquery name="TripQuery" dataSource="CompassTravel">
    UPDATE Trips SET baseCost = baseCost * 1.05
</cfquery>


Exercise: using SQL UPDATE with cfquery

In this exercise, you will develop a page to increase the price of every trip by 10%. This page runs only once and is not part of the Trips Maintenance application. This exercise shows how to update many database rows using a single SQL UPDATE statement and the ColdFusion cfquery tag.

To update multiple database rows using SQL UPDATE with cfquery:

  1. In an editor, open a new page and save it as priceincrease.cfm in the my_app directory.
  2. Remove any lines of code that your editor added.
  3. Add the following code:
    4. <!---Routine to increase trip price by 10% --->
<cfquery name="TripQuery" dataSource="CompassTravel">
    UPDATE trips SET price = price * 1.1
</cfquery>
<cfoutput> New prices are now in effect.</cfoutput>
  4. Save the page then test the page by doing the following tasks:
    1. Use the Trip Maintenance application to take note of the price of any trip by viewing tripdetail.cfm in a browser.
    2. Test by opening the priceincrease.cfmpage in your browser. This page automatically updates the prices in the trips table.
    3. Use the Trip Maintenance application to verify that the query successfully increased the price of the trip by 10%. To do this, navigate to the tripdetail.cfm and locate the trip you noted in step 4a. The price of this trip is now 10% higher.


Summary

In this lesson you used the cfinsert and cfupdate tags to add and update data to a SQL table. You also have used the SQL UPDATE statement in conjuction with the cfquery tag to effect a trip price increase for all rows in the Trips table.

You have completed the Getting Started tutorial. You should understand how you can combine CFML and SQL to develop powerful applications. When compared with traditional development methods, ColdFusion helps speed the development in hand crafting a database solution like the one in this tutorial. Remarkably, however, depending on the editor or IDE that you use to develop applications, much of the work in this tutorial can be autogenerated using built-in wizards, which simplifies the development process even more.

Previous


About This Book

Migrating ColdFusion 5 Applications provides migration and incompatibility information for anyone who is migrating applications from ColdFusion Server 5 to ColdFusion MX.

Contents
  • Developer resources
  • About ColdFusion documentation
  • Getting answers
  • Contacting Macromedia
Next


About ColdFusion documentation

ColdFusion documentation is designed to provide support for the complete spectrum of participants. The print and online versions are organized to let you quickly locate the information that you need. The ColdFusion online documentation is provided in HTML and Adobe Acrobat formats.


Printed and online documentation set

The ColdFusion documentation set consists of the following titles:

Book | Description
Installing ColdFusion MX | Describes system installation and basic configuration for Windows NT, Windows 2000, Solaris, Linux, and HP-UX
Administering ColdFusion MX | Describes how to connect your data sources to the ColdFusion Server, configure security for your applications, and how to use ClusterCATS to manage scalability, clustering, and load-balancing for your site
Developing ColdFusion MX Applications with CFML | Describes how to develop your dynamic web applications, including retrieving and updating your data, using structures, and forms
Getting Started Building ColdFusion MX Applications | Contains an overview of ColdFusion features and application development procedures. Includes a tutorial that guides you through the process of developing an example ColdFusion application.
Using Server-Side ActionScript in ColdFusion MX | Describes how Flash movies executing on a client browser can call ActionScript code running on the ColdFusion server. Includes examples of server-side ActionScript and a syntax guide for developing ActionScript pages on the server.
Migrating ColdFusion 5 Applications | Describes how to migrate a ColdFusion 5 application to ColdFusion MX. This book describes the code analyzer that evaluates your ColdFusion 5 code to determine any incompatibilities within it.
CFML Reference | Provides descriptions, syntax, usage, and code examples for all ColdFusion tags, functions, and variables
CFML Quick Reference | A brief guide that shows the syntax of ColdFusion tags, functions, and variables
Working with Verity Tools | Describes Verity search tools and utilities that you can use for configuring the Verity K2 Server search engine, as well as creating, managing, and troubleshooting Verity collections.
Using ClusterCATS | Describes how to use Macromedia ClusterCATS, the clustering technology that provides load-balancing and failover services to assure high availability for your web servers.


Migrating ColdFusion 5 Applications

This chapter describes the known compatibility issues between ColdFusion Server 5 and ColdFusion MX. For late-breaking known compatibility issues, see the “Migrating ColdFusion 5 Applications” section of the Release Notes on the Macromedia website.

  • Migrating to ColdFusion MX
  • Planning your migration
  • Using the ColdFusion Code Compatibility Analyzer
  • Using the settings migration wizard
  • CFML tags and attributes
  • CFML functions and variables
  • Database operations
  • Localization
  • Other changes
  • Tag and function examples
Next


Migrating to ColdFusion MX

When you migrate your existing ColdFusion Server 5 applications to ColdFusion MX, you might encounter a few incompatibilities between ColdFusion 5 and ColdFusion MX. Macromedia strongly encourages you to develop a migration plan for porting existing ColdFusion 5 applications to ColdFusion MX. For more information, see Planning your migration.

Whether you encounter incompatibilities depends on the features of ColdFusion and the CFML elements that your existing applications use. This book lists all of the known incompatibilities that you might encounter, and suggests possible fixes. Also, you can use the Code Compatibility Analyzer to facilitate locating and fixing incompatible code; for more information, see Using the ColdFusion Code Compatibility Analyzer.


Planning your migration

To facilitate the migration process, Macromedia recommends that you develop a structured migration strategy. The migration steps offered here are provided as examples. Because every application is different, you must tailor your own migration strategy to meet your environment’s needs.

Adapt the following steps to fit your needs:

  1. Study the migration section of the release notes and this book to anticipate the compatibility issues that might affect your system.
  2. Archive and deploy your existing ColdFusion 5 application to a test server.
  3. Migrate your production databases to the test server. If you have not already done so, migrate the data sources in your ColdFusion 5 application to ColdFusion MX.
  4. Ensure that the application is functioning properly on the test server before upgrading it to ColdFusion MX. For detailed server specifications, contact your website administrator or hosting provider.
  5. Install ColdFusion MX on the test server.
  6. Test the code in your application using the ColdFusion Code Compatibility Analyzer.

    7. Ensure that you specify the location of any custom tags or other code outside of the ColdFusion MX web root directory. For more information, see Using the ColdFusion Code Compatibility Analyzer.

  7. Based on the results of the Code Compatibility Analyzer report and the incompatibilities listed in this guide, make a migration plan. For example, you might plan to immediately fix code that causes errors, such as dbtype=“dynamic” in query tags, and to schedule and prioritize other fixes, such as replacing deprecated tags and using new functionality.
  8. Using a source control system, make the necessary changes to your ColdFusion application and run the application on your test server. Ensure that you test all application features under load, not just with a few users.

Your application is now ready for production on ColdFusion MX.


Using the ColdFusion Code Compatibility Analyzer

To isolate compatibility issues between ColdFusion MX and ColdFusion Server 5, use the Code Compatibility Analyzer to check your ColdFusion pages for potential incompatibilities. Based on diagnostic information, the Code Compatibility Analyzer issues error and information messages to alert you to possible compatibility issues.

The Code Compatibility Analyzer detects the following issues:

  • Obsolete CFML features in ColdFusion MX
  • Deprecated CFML features in ColdFusion MX
  • CFML features that might produce different behaviors in ColdFusion MX
  • CFML syntax errors

To access the Code Compatibility Analyzer, click the link in the ColdFusion Administrator.

When using the Code Compatibility Analyzer, follow these guidelines:

  • To avoid time-consuming operations and possibly degraded server performance for an extended period of time, do not run the Code Compatibility Analyzer on multiple application directories.
  • When testing only for possible ColdFusion MX incompatibilities, turn off CFML validation in the Code Compatibility Analyzer administration page.
  • To validate strict CFML syntax, turn on CFML validation. You can also validate individual tags and functions. For more information, see the online Help in the Code Compatibility Analyzer administration page.


Using the settings migration wizard

If you have ColdFusion 5 installed on the same computer as ColdFusion MX, you are prompted to migrate your ColdFusion settings into ColdFusion MX. For Windows, you are prompted immediately after you finish the installation; for UNIX, you are prompted the first time that you open the ColdFusion Administrator.

If you choose to skip the migration, you can do it later (see the instructions in Migrating settings later in Windows or Migrating settings later in UNIX). However, running the wizard later might overwrite new ColdFusion MX settings, because the wizard copies settings from the ColdFusion 5 configuration.


Limitations of the wizard

The following table lists the known limitations of the settings migration wizard:

Limitation | Remedy
Does not migrate CORBA connector settings. | Manually reconfigure them in the ColdFusion Administrator.
Does not migrate DB2 data sources (ODBC and Native). | Manually recreate these data sources after installing ColdFusion MX.
Might incorrectly set the Port value in the JDBC Type IV Informix driver that it creates for an ODBC data source that uses the Native Informix driver. | Edit the data source in the ColdFusion Administrator to include the correct port value.
Might incorrectly set the Port value in the JDBC Type IV Informix driver that it creates for an ODBC data source that uses the Sybase ASE driver or Native driver.
The BLOB and CLOB options are not selected for a data source by default, even if a data source supports BLOBs and CLOBs (for example, Oracle BLOBs and CLOBs, SQL Server text columns, or Microsoft Access memo columns). | Manually select the appropriate Long Text Retrieval option in the ColdFusion Administrator advanced settings for Data Source Names (DSNs).
If your ColdFusion 5 log directory setting is a value other than the default (cfusion\log), the wizard migrates it, but ColdFusion MX uses the default value until you restart ColdFusion MX. (For this reason, the migration log always resides in cfusion\log, no matter where your other log files are located.) | Restart ColdFusion MX after completing the migration.


Migrating settings later in Windows

To run the settings migration wizard later, you must configure the software to prompt you again to perform the migration.

To migrate settings later in Windows:

  1. Close the ColdFusion Administrator if it is open.
  2. Change the value of the following registry key from 0 to 1:

    3. HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\Install Data\Neo\migrate

  3. Restart the ColdFusion Administrator.

    4. You are prompted again to perform the migration.

  4. Click Yes, and follow the on-screen instructions.


Migrating settings later in UNIX

To run the settings migration wizard later, you must configure the software to prompt you again to perform the migration.

To migrate settings later in UNIX:

  1. Stop the ColdFusion Administrator if it is running.
  2. Create a file called upgrade (it can be blank) in your cf_root/bin directory.

    3. Note: The user account under which ColdFusion MX runs must have read/write access to this file. The file is deleted after the migration completes.

  3. Start the ColdFusion Administrator.

    4. You are prompted again to perform the migration.

  4. Click Yes, and follow the on-screen instructions.


CFML tags and attributes

The following table describes the tags and attributes in ColdFusion MX that differ from ColdFusion Server 5:

Tag

Status

Compatibility issue
For more information
cfapplet
Changed
Can now be used outside the context of cfform.
See cfapplet in CFML Reference.
cfapplication
Changed
Setting clientstorage = "registry" is obsolete in UNIX versions of ColdFusion MX.
See cfapplication in CFML Reference.
cfauthenticate,
cfimpersonate
cfinternaladmin
security
cfnewinternal
adminsecurity
Obsolete
ColdFusion MX is based on a completely different security model than ColdFusion 5.
See the chapter on application Security inDeveloping ColdFusion MX Applications with CFML.
cfcache
Changed
The timeout attribute is deprecated in ColdFusion MX; it will be obsolete in later versions. Use timespan instead.
The new timespan attribute specifies a decimal number of days between when the page containing the cfcache tag is first cached, and when the cache contents are automatically flushed.
See cfcache in CFML Reference.
action="cache" now caches on both the server and client, and the cache and optimal values are equivalent.
A new action value, serverCache, caches pages on the server only. It is identical in function to the cache value in ColdFusion 5.
The directory and cacheDirectory attributes are now equivalent. You can use either attribute with any action. (In ColdFusion 5, you can only use directory with action="flush", and you use cacheDirectory with all other action values.)
The port and protocol values now default to the values used to initially access the page. In earlier releases, the port default was “80”, and the protocol default was http.
action="flush" now correctly expires a cached page in the server, the client, or both locations.
The cfcache.map file now contains the template name and source timestamp.
cfcatch
Changed
cfcatch.Message gets the current values every time an exception is thrown, and ColdFusion MX ignores any cfset assignment to a cfcatch member.
To remedy this, construct a new message or variable to make extensions to changes in cfcatch values.
See the section about CFCATCH variablesL in CFML Reference.
cfcatch.Message returns a different SQLState value for Type 4 database drivers; this affects the NativeErrorCode variable as well.
Can no longer use cfcatch to catch function validation errors; use the ColdFusion MX compiler instead.
cfcol,
cftable
Changed
If you use the cfcol header attribute without any text, and the cftable colheader attribute, then ColdFusion MX displays the header as true. ColdFusion 5 displays the header as TRUE.
See cfcol and cftable in CFML Reference.
cfcollection
Changed
The action attribute is now optional, and its default value is list, a new value in ColdFusion MX.
See cfcollection in CFML Reference, and Working with Verity Tools.
Added an attribute called name, which is required when action = "list". The name attribute provides the name for the query results.
When you use cfcollection with action = "list" and name = "<query_results_name>", you retrieve a table with the properties for every Verity collection that is registered by ColdFusion or the K2 Server.
cfdirectory
Changed
(Windows) No longer returns rows for '.' and '..' in the query results, but only subdirectories, like on UNIX.
If your application has code to skip these rows (for example, startrow="3"), you must change it.
See cfdirectory in CFML Reference.
(Windows) No longer supports sort="temporary", and it only supports sorting on the ReadOnly and Hidden attributes.
(UNIX) When action=list, cfdirectory only reports the ReadOnly and Hidden attributes.
cferror
Changed
type="monitor" is obsolete in ColdFusion MX.
See cferror in CFML Reference.
cfform
Changed
ColdFusion MX only uses the cfinput tag’s checked attribute if the corresponding form field value is undefined. ColdFusion 5 used the checked attribute if the field was undefined, or if it was defined but not equal to any of the specified options.
For example, if you use a cfparam tag to default form.foo to "false" before the following cfinput tags, then neither of the options are checked. In ColdFusion 5, the "yes" option is checked.
<cfinput name="foo" type="radio" value="yes" checked>
<cfinput name="foo" type="checkbox" value="no">
See cfform in CFML Reference.
The enablecab attribute is deprecated in ColdFusion MX; it will be obsolete in later versions.
cfgraph,
cfgraphdata
Deprecated
Will be obsolete in later versions of ColdFusion MX. These tags render differently than in ColdFusion 5. Use the new graphing tags instead: cfchart, cfchartdata, and cfchartseries.
See the chapter on charting and graphing data in Developing ColdFusion MX Applications with CFML.
cfhttp
Changed
The cfhttp response headers in ColdFusion MX differ from those in ColdFusion 5, as follows:
  • Mixed Case (returned by the server without changes) in ColdFusion MX; uppercase in ColdFusion 5
  • Random order in ColdFusion MX; alphabetical order in ColdFusion 5
  • “Status Code: 200” is followed by “OK” in ColdFusion MX (returned by the server without changes), and by “SUCCESS” in ColdFusion 5
See cfhttp in CFML Reference.
The timeout attribute requires the Java Development Kit (JDK) version 1.4; otherwise, ColdFusion MX ignores this attribute.
cfindex
Changed
You can use the cfindex tag with the query attribute and type="file" or type="path", for all actions that require information from the key attribute.
See cfindex in CFML Reference and Using the cfindex tag in ColdFusion MX.
cfldap
Changed
You can no longer sort cfldap query results on the client side using the sort attribute. The sort attribute triggers a server-side sort. If the LDAP server does not support server-side sorting, cfldap throws an error.
The sort order depends on the LDAP server; for example, iPlanet Directory Server 5.0, Novell 6.0 server, Oracle Internet Directory 9i, Microsoft Active Directory, and others might each sort differently.
To do client-side sorting on the cfldap query results, use the ColdFusion Query of Queries feature.
See cfldap in CFML Reference.
When action=query and dn is in the list of attributes, cfldap returns each Distinguished Name (DN) with a comma followed by a space. (In ColdFusion 5, cfldap did not return DNs in a consistent format.)
If you select the referral attribute, cfldap returns the name of the referred server before the results.
For example, if the referred server is server1.rnd.anytown.anycorp.com:123, the results could look as follows: DN:ldap://server1.rnd.anytown.anycorp.com:123/uid=bparker, ou=People, dc=siroe, dc=com, dc=siroe, dc=co, CN:Barry Parker, OU:Product Development, People
cflog
Changed
The thread, date, and time attributes are deprecated, and will be obsolete in later versions of ColdFusion MX. All of these attributes default to Yes. If you set any of these attribute values to No, ColdFusion MX throws a runtime exception.
See cflog in CFML Reference.
cfloop
Changed
ColdFusion MX returns struct keys in the order that you create them. ColdFusion 5 returns struct keys in alphabetical order.
If you need sorted struct values or keys, use the StructSort() and StructKeySort() functions.
See cfloop in CFML Reference.
cfmail
Changed
ColdFusion MX formats undeliverable mail differently than in ColdFusion 5. If you have any custom code that relies on this format, you must change it.
See cfmail in CFML Reference.
cfparam
Changed
ColdFusion MX correctly disallows the assignment of complex data types (such as array, binary, query, and struct) to the client scope in this tag.
See cfparam in CFML Reference.
cfprocparam
Changed
The maxrows attribute is obsolete in ColdFusion MX. If you have ref cursors in packages or stored procedures, use cfprocresult instead. This causes Datadirect JDBC to place the Oracle ref cursors into a result set. (Note: you cannot use this method with the Oracle ThinClient JDBC drivers.)
See cfprocparam and cfprocresult in CFML Reference.
The cfprocparam tag ignores the dbvarname attribute for all drivers. (ColdFusion 5 used it for Sybase, Oracle, and Informix native drivers.) ColdFusion MX is a JDBC client which does not support named parameter passing like the Sybase ctlib and Oracle oci libraries.
cfquery
Changed
The cfquery tag disallows SQL reserved words as variable or column names in a Query of Queries, unless they are escaped. To escape a reserved word, enclose it in brackets; for example: select [COUNT] from myTable or
select [FROM] from popQuery
See cfquery in CFML Reference.
Measures the timeout value in seconds, instead of milliseconds as in ColdFusion 5. You must convert each timeout value from milliseconds to seconds.
cfquery,
cfinsert,
cfgridupdate,
cfupdate,
cfstoredproc
Changed
In ColdFusion MX, all values of the dbtype attribute are deprecated except for dbtype="query", and dbtype="dynamic" is obsolete.
This is because ColdFusion MX uses the data source services provided by the underlying J2EE server, which provides better scaling and connection support in most cases. However, it only supports passing in the username and password, which is insufficient to define a data source. ColdFusion 5 can do this because it uses Open Database Connectivity (ODBC) to establish a database connection.
To work around this, define a data source to connect to the database.
See cfquery, cfinsert, cfgridupdate, cfupdate, and cfstoredproc in CFML Reference, and the “Data Source Management” chapter of Administering ColdFusion MX.
The dbserver, dbname, connectstring, provider, and providerdsn attributes are obsolete in ColdFusion MX.
cfregistry
Deprecated for UNIX
Registry operations will be obsolete in later UNIX versions of ColdFusion MX.
See Using cfregistry in ColdFusion MX.
Changed
In Windows, you should not use cfregistry to read ColdFusion server settings--such as the mail root and information about Verity collections and scheduled tasks--because much of this information is no longer stored in the registry, or it is stored in a different location in the registry. The ColdFusion-related values that are stored in the registry are subject to change.
cfreport
Changed
This tag no longer manages the data connection for a Crystal report. Passes datasource, username, and password attributes to the Crystal Reports server for it to manage the data connection directly.
See cfreport in CFML Reference.
cfservlet
Deprecated
Will be obsolete in later versions of ColdFusion MX.
See cfservlet in CFML Reference.
In cfservlet tags, you can only call servlets that were created in JRun version 3.1 or earlier.
cfservletparam
Deprecated
Will be obsolete in later versions of ColdFusion MX.
See cfservletparam in CFML Reference.
cfsetting
Changed
The catchExceptionsByPattern attribute will be obsolete in later versions of ColdFusion MX. ColdFusion MX uses best-fit exception handling. You can no longer set catchExceptionsByPattern to No to use first-fit exception handling.
See cfsetting in CFML Reference.
cfswitch
Changed
You can no longer have code inside a cfswitch tag that is not in a cfcase or cfdefaultcase tag. ColdFusion 5 erroneously ignores the code, whereas ColdFusion MX correctly throws a compiler error.
See cfswitch in CFML Reference.

The ColdFusion section of the Macromedia website contains the most current compatibility information. For more information, go to http://www.macromedia.com/coldfusion.


CFML functions and variables

The following table describes other CFML functions and variables in ColdFusion MX that differ from ColdFusion Server 5:

Function
Status
Issue
For more information
ArrayAvg(), ArrayMin(),
ArrayMax(), ArraySum()
Changed
Returns “0” when used with an empty array. ColdFusion 5 returns infinity (1.#INF).
See ArrayAvg(), ArrayMin(), ArrayMax(), and ArraySum() in CFML Reference.
AuthenticatedContext(),
AuthenticatedUser(),
IsAuthenticated(),
IsAuthorized(),
IsProtected()
Obsolete
ColdFusion MX is based on a completely different security model than ColdFusion 5.
See the “Application Security” chapter in Developing ColdFusion MX Applications with CFML.
DateDiff()
Changed
In ColdFusion 5, there is one less second in a minute when calculating a negative difference. For example, it returns 60 seconds between 03:44:23 and 03:45:23, but -59 seconds between 03:45:23 and 03:44:23.
ColdFusion MX calculates negative differences correctly, so if your application contains code that adjusts the ColdFusion 5 results, you might have to change it.
See DateDiff() in CFML Reference.
DeleteClientVariable()
Changed
Returns False when the variable does not exist. ColdFusion 5 ignores the function call.
See DeleteClientVariable() in CFML Reference.
GetBaseTagList()
Changed
Returns prefixed custom tags found in the tag stack in the format x:tag, where x is the prefix that you specified.
See GetBaseTagList() in CFML Reference.
GetLocale()
Changed
When the locale has not been explicitly set using SetLocale(), GetLocale() returns the default locale of the client computer’s operating system. In ColdFusion 5, GetLocale() returns English(US) when the locale has not been explicitly set.
See GetLocale() and SetLocale() in CFML Reference.
GetTempDirectory()
Changed
(Windows) Returns the temporary directory for the embedded Java application server, instead of the temporary directory for the Windows operating system, as in ColdFusion 5.
See GetTempDirectory() in CFML Reference.
IsArray()
Changed
Returns True with a QueryColumn argument. You can change the value of an array element, but you cannot add or remove an element.
See QueryColumn object, and IsArray() in CFML Reference.
IsWDDX()
Changed
Returns No for arrays and other complex values. ColdFusion 5 returns an error. (Both versions accept a basic value, such as a string, number, logical value, or date and time value. )
See IsWDDX() in CFML Reference.
Len()
Changed
When calculating a length, a string-processing function processes an ASCII 0 (NUL) character and continues to process subsequent characters of the string, if any. In ColdFusion 5, these functions did not process any subsequent characters of the string after processing the ASCII 0 (NUL) character.
See Len() in CFML Reference.
ListSetAt()
Changed
No longer changes the first delimiter in the list to the first delimiter specified in the function.
See ListSetAt() in CFML Reference.
ListSort()
Changed
In a descending sort with textnocase, ListSort() returns elements in a different order than in ColdFusion 5.
See Using ListSort() in ColdFusion MX.
LSCurrencyFormat()
Changed
Returns a negative number when passed a negative number.
See Localization.
With the local argument, returns the currency in the locale’s standard format, such as £ for pounds in the English(UK) locale.
With the international argument, returns the currency with its international currency code, such as AUD for the Australian dollar.
LSIsDate()
Changed
Supports full date and full datetime as parameters, which include the name of the day.
LSParseDateTime()
Changed
For English (US) locales, the following date mask format is obsolete in ColdFusion MX: 23:15:16 4 Sept. 1998. Use a Java standard date format instead.
REFind
REReplace()
REFindNoCase()
REReplaceNoCase()
Changed
Excludes questionable punctuation, such as +, $, and =, in the [[:punct:]] class of regular expression functions.
See REFind(), REReplace(), REFindNoCase(), and REReplaceNoCase() in CFML Reference.
Recognizes accented letters in the appropriate character classes, such as :upper:, :lower:, :alpha:, and so on.
Does not allow the backslash character (\) in a regular expression, even if it is inside a character class []. You must escape it by prefixing an additional backslash (\\). (ColdFusion 5 does not require you to escape a backslash in this case.)
REReplace(),
REReplaceNoCase()
Changed
In replacement strings, the following character pairs now represent case conversion codes: \E, \l, \L, \u, and \U.
If your ColdFusion 5 application has a replacement string with one of these character pairs, escape it by prefixing it with a backslash (for example, \\u).
To include special characters for backrefs (\1), prefix them with an additional blackslash (for example, \\1). To include a real backref, prefix an additional backslash (for example, \\\1).
For case conversion codes, additional blackslash prefixes alternate between escaping the code and not. For backrefs, they always escape.
See REReplace() and REReplaceNoCase() in CFML Reference.
StructKeyList
Changed
Returns struct keys in the order they are created, not in alphabetical order like in ColdFusion 5.
If you need sorted struct values or keys, you can use the StructSort and StructKeySort functions.
See StructKeyList() in CFML Reference.

Note: The date pivot point for calculating the century in a two-digit year has changed from ColdFusion 5, affecting the results from date functions. For more information, see Date pivot point for two-digit years.

The ColdFusion section of the Macromedia website contains the most current compatibility information. For more information, go to http://www.macromedia.com/coldfusion.


Database operations

ColdFusion MX uses JDBC drivers to interact with databases; for example, to query, write, and update a database. (JDBC is an Application Programming Interface (API) for Java programs to access data.) To connect to Open Database Connectivity (ODBC) data sources, you can use the bundled Merant Type 4 database drivers or the SQL Link Type 3 database drivers. ColdFusion MX no longer uses the JDBC-ODBC bridge driver.

This section describes the known incompatibilities between the ODBC features of ColdFusion 5 and the JDBC features of ColdFusion MX, in addition to those that are documented in CFML tags and attributes and CFML functions and variables (for example, cfquery, cfcatch, and cfreport).

For more information about the Merant JDBC drivers included with ColdFusion MX, see http://www.merant.com.


Connecting to a data source with ODBC Socket

In ColdFusion 5, an ODBC Data Source Name (DSN) entry that was created with the ODBC Data Source Administrator would automatically show up in the list of data sources in the ColdFusion Administrator. It does not in ColdFusion MX; you must manually add the ODBC DSN entry.

To manually add the ODBC DSN entry:

  1. In the ColdFusion Administrator, select Data & Services > Data Sources.
  2. In the Add New Data Source Name box, do the following:
    1. In the Data Source Name text box, enter the data source name.

      2. You can use the same name as the ODBC DSN entry.

    2. In the Driver drop-down list box, select ODBC Socket.
    3. Click Add.
  3. In the ODBC DSN drop-down list box, select the ODBC DSN name.
  4. Click Submit.

For more information about data source management, see Administering ColdFusion MX.


Session management

ColdFusion MX now uses J2EE sessions as its default session management technique. For more information about using persistent data and locking, see Developing ColdFusion MX Applications with CFML.


QueryColumn object

The QueryColumn object is even more like an array than in ColdFusion 5, as shown by the following examples:

  • The QueryColumn object is derived by referencing a query using associative array notation; for example:
    • query1['firstName']
  • You can set a query column to an array element; for example:
    • <cfset query1['col'] = array2['moo']>
  • The following code returns True in ColdFusion MX, and False in ColdFusion 5:
    • #isArray(query1['firstName'])#
  • The following code works in ColdFusion MX, and produces an error in ColdFusion 5:
    • <cfset joeArray[1] = query1['firstName']


Data type of query results

ColdFusion 5 stores data in the query object as a string, regardless of how the data is stored in the database. When it outputs a piece of data, it just writes out the string. ColdFusion MX stores data in the query object differently, depending on its database type (for example, it may store a number as a Java Double). ColdFusion MX outputs the data by converting the stored type to a string, which might differ from the string that ColdFusion 5 outputs. If you need your output to be in a particular format, use the number and/or date format functions.


Appearance of query results

Certain database and operating system combinations can lead to query data being returned with space characters appended to the end. If you encounter this whitespace padding, you can remove it using the SQL command rtrim(), if your database supports the SQL rtrim function. For example, if SELECT ColA, ColB FROM TableA returns results for ColB with whitespace padding, you can rewrite the query as follows:

SELECT ColA, rtrim(ColB) AS ColB FROM TableA


Localization

This section describes the changes between ColdFusion 5 and ColdFusion MX that affect locale functions. It contains the following topics:

  • Extended character code support
  • Changes to formatting functions
  • Other locale-specific changes

Note: Results from localization functions might differ, depending on your Java Runtime Environment (JRE). The contents of this section reflect tests on the SUN JRE version 1.4 and the IBM JRE version 1.3.0. Macromedia has also tested using the SUN JRE version 1.3.1_01; however, many of these tests failed on locales other than English(US).


Extended character code support

ColdFusion MX supports character code values 0–65535, whereas ColdFusion 5 supports 1-255. This affects string-processing functions. For more information, see Len() in CFML functions and variables.


Support for new currency formats

ColdFusion MX recognizes new currency formats for new locales. For example, when a Euro currency is passed into the LSIsCurrency function, ColdFusion MX returns Yes if the locale is a Euro member, and No if not. Also, LSIsCurrency() now returns “yes” for the locales and currency formats listed in the following table:

Locale | Newly supported currency formats
English(Australian) | AUD123,456.78
English(Canadian) | CAD123,456.78
English(New Zealand) | NZD123,456.78
English(UK) | £123,456.78 GBP123,456.78
French(Belgian) | 123.456,78 123.456,78 FB BEF123.456,78
French(Canadian) | 123 456,78 123 456,78 $ CAD123 456,78
French(Standard) | 123 456,78 123 456,78 F FRF123 456,78
French(Swiss) | 123'456.78 SFr. 123'456.78 CHF123'456.78
German(Austrian) | öS 123.456,78 ATS123.456,78
Italian(Swiss) | 123'456.78 SFr. 123'456.78 CHF123'456.78
Norwegian(Bokmal), Norwegian(Nynorsk) | 123 456,78 kr 123 456,78 NOK123 456,78
Portuguese(Standard) | 123.456,78 Esc. PTE123.456,78
Portuguese(Brazilian)* | 12 de outubro de 1954 05h04min30s PST
Spanish(Mexican) | 123,456.78 $123,456.78 MXN123,456.78
Swedish | 123 456,78 123 456,78 kr SEK123 456,78

* In ColdFusion MX for Portuguese (Brazilian), the Java medium time format (for example, 06:55:27) does not work. However, the short, long, and full formats all work as expected; for example, 05h04min30s PST, 5h4min30s PST, and 05:04.

For more information, see LSIsCurrency() in CFML Reference.


Changes to formatting functions

ColdFusion MX uses Java standard locale formatting rules on all platforms. ColdFusion 5 uses Windows or UNIX locale formatting rules, depending on the ColdFusion platform. For information on Java standard locale formatting rules, see the Java documentation for the Locale class (java.util.Locale) at http://java.sun.com/j2se/1.3/docs/api/index.html.

Some functions in ColdFusion MX produce slightly different results than in ColdFusion 5. Many of these differences are improvements. For example, in ColdFusion MX, LSCurrencyFormat() returns the correct international currency code for countries other than the US, and correctly rounds the currency values for countries whose currency does not include cents. The greatest improvement is that the same code produces the same results, regardless of the ColdFusion platform.

Some of the differences might require a slight adjustment in your ColdFusion application. For example, LSCurrencyFormat() in ColdFusion MX formats some negative currency values differently than in ColdFusion 5, such as inserting a leading minus sign (–) instead of enclosing the value in parentheses.

The rest of this section describes changes that affect specific locales and every locale.


Changes to formatting functions for different locales

The following table shows the locales in which one or more functions produce slightly different results between ColdFusion 5 and ColdFusion MX:

Locale | Function | ColdFusion 5 results | ColdFusion MX results
English(Australian) | LSCurrencyFormat(123456.78,"international") | USD123,456.78 | AUD123,456.78
 | LSCurrencyFormat("-1234.56","none") | (1,234.56) | -1,234.56
English(Canadian) | LSCurrencyFormat(123456.78,"international") | USD123,456.78 | CAD123,456.78
 | LSCurrencyFormat("-1234.56","none") | (1,234.56) | -1,234.56
English (New Zealand) | LSCurrencyFormat(123456.78,"international") | USD123,456.78 | NZD123,456.78
 | LSCurrencyFormat("-1234.56","none") | (1,234.56) | -1,234.56
English(UK) | LSCurrencyFormat(123456.78,"local") | $123 456.78 | £123,456.78
 | LSCurrencyFormat(123456.78,"international") | USD123,456.78 | GBP123,456.78
 | LSCurrencyFormat("-1234.56","none") | (1,234.56) | -1,234.56
English(US) | LSParseDateTime("23:15:16 4 Sept. 1998")* | {ts '1998-09-04 23:15:16'} | invalid date format error
French(Belgian) | LSCurrencyFormat(123456.78,"none") | 123 456,78 | 123.456,78
 | LSCurrencyFormat(123456.78,"local") | 123 456,78 F | 123.456,78 FB
 | LSCurrencyFormat(123456.78,"international") | FRF123 456,78 | BEF123.456,78
French(Canadian) | LSCurrencyFormat(123456.78,"local") | 123 456,78 F | 123 456,78 $
 | LSCurrencyFormat(123456.78,"international") | FRF123 456,78 | CAD123 456,78
 | LSCurrencyFormat("-1234.56","none") | -1 234,56 | (1 234,56)
French(Swiss) | LSCurrencyFormat(123456.78,"local") | 123 456,78 F | SFr. 123'456.78
 | LSCurrencyFormat(123456.78,"international") | FRF123 456,78 | CHF123'456.78
German(Austrian) | LSCurrencyFormat(123456.78,"local") | 123.456,78 DM | öS 123.456,78
 | LSCurrencyFormat(123456.78,"international") | DEM123.456,78 | ATS123.456,78
Italian(Standard) | LSCurrencyFormat(123456.78,"none") LSCurrencyFormat(123456.78,"none") | 12.345.678 | 123.457
Italian(Swiss) | LSCurrencyFormat(123456.78,"none") | 12.345.678 | 123'456.78
 | LSCurrencyFormat(123456.78,"local") | L. 12.345.678 | SFr. 123'456.78
 | LSCurrencyFormat(123456.78,"international") | ITL12.345.678 | CHF123'456.78
Portuguese (Brazilian) | LSCurrencyFormat("-1234.56","none") | (1.234,56) | -1.234,56
Portuguese (Standard) | LSCurrencyFormat("-1234.56","none") | (1.234,56) | -1.234,56
 | LSCurrencyFormat(123456.78,"local") | R$ 123.456,78 | 123.456,78 Esc.
 | LSCurrencyFormat(123456.78,"international") | BRL123.456,78 | PTE123.456,78
Spanish(Mexican) | LSCurrencyFormat(123456.78,"none") | 12.345.678 | 123,456.78
 | LSCurrencyFormat(123456.78,"local") | 12.345.678 pta | 123,456.78
 | LSCurrencyFormat(123456.78,"international") | ESP12.345.678 | MXN123,456.78
 | LSCurrencyFormat("-1234.56","none") | -123.456 | (1,234.56)
Spanish (Standard), Spanish(Modern) | LSCurrencyFormat(123456.78,"local") | 12.345.678 pta | 123.457 Pts
 | LSCurrencyFormat(123456.78,"none") | 12.345.678 | 123.457
Swedish | LSCurrencyFormat(123456.78,"none") | 123.456,78 | 123 456,78

* The medium date format for English(US) has changed to the Java standard; for example, “Sept 4, 1998 11:15:16 PM" and "11:15:16 PM Sept. 4, 1998" are valid. For a list of valid date formats, see the Java documentation for the java.text.DateFormat class at .

Spanish (Standard) and Spanish(Modern) map to the same Java locale ES_es. Therefore, whether you set the locale to Spanish(Modern) or Spanish(Standard), GetLocale() returns Spanish(Standard).

For more information, see CFML Reference for the appropriate function.


Changes to formatting functions for every locale

The following table outlines changes to formatting functions that apply to every locale:

Function
Description of change
IsDateFormat()
When no mask is specified, ColdFusion MX returns the Java medium date format for the locale. ColdFusion 5 returns one of two default masks, depending on the locale:
  • For a locale where the date ends with the year, the default mask is dd-mmm-yy
  • For a locale where the date begins with the year, the default mask is yyyy-mmm-dd
IsTimeFormat()
ColdFusion MX supports the following masks for IsTimeFormat():
  • h:m:s lsTimeFormat(6:39,"h:m:s") returns 06:39:0
  • hh:mm:ss lsTimeFormat(6:39,"hh:mm:ss") returns 06:39:00
  • hh:mm:ss t lsTimeFormat(6:28:26,"hh:mm:ss t") returns 06:28:26 A
  • hh:mm:ss tt lsTimeFormat(6:28:26,"hh:mm:ss tt") returns 06:28:26 AM
LSCurrencyFormat()
LSEuroCurrencyFormat()
ColdFusion 5 put “EUR” as the international currency for every locale, even if the locale did not support the Euro. For example, LSEuroCurrencyFormat(123.45, "international") returned "EUR123.45", even for an English(US) locale.
ColdFusion MX uses the Java standard locales. Therefore, ColdFusion MX processes LSCurrencyFormat() and LSEuroCurrencyFormat() as follows:
  • LSCurrencyFormat() returns the non-Euro currency format for all locales, even if the locale is a member of the Euro countries. For example, for the French(Standard) locale, LSCurrencyFormat() returns the French franc as the currency symbol, instead of the Euro.
  • LSEuroCurrencyFormat() only returns the Euro currency format if the set locale is a Euro member country. Otherwise, it returns the set locale’s currency format or symbol. For example, LSEuroCurrencyFormat(-1234.56) returns -1 234,56 € for the French(Standard) locale, but returns ($1,234.56) for the English(US) locale.
LSDateFormat()
In ColdFusion 5, for the date parameter, you can only use a date/time object in the range of 100 AD–9999 AD. ColdFusion MX does not have this limitation.
In ColdFusion MX, LSDateFormat() returns the appropriate date for the set locale. For example, LSDateFormat(12/01/02) returns Jan-12-2002 if the locale is set to English(UK), and Dec-01-2002 if the set locale is English(US).
In ColdFusion 5, LSDateFormat() throws an error or returns an incorrect format.
LSDateFormat()
LSTimeFormat()
If you pass an invalid mask into LSTimeFormat() or LSDateFormat(); for example, "dd-mm-yymm", the function outputs the invalid characters in both ColdFusion 5 and ColdFusion MX. However, ColdFusion 5 delimits each character of the output with an apostrophe (') character.
LSIsCurrency()
When a Euro currency is passed into the LSIsCurrency function, ColdFusion MX returns "yes" if the locale is a Euro member, and "no" if not.
LSIsDate()
In ColdFusion MX, you can pass in dates with the full date and full datetime parameters. These formats include the name of the day (for example, Wednesday).
LSParseDateTime()
In earlier versions, you could not pass in a time zone value such as “EST”. Now you can, but ColdFusion MX processes this information as follows:
  • If the time zone specified in the date/time string parameter is different from the time zone setting of the computer hosting ColdFusion MX, ColdFusion MX changes the time value in the parameter to its equivalent value in the computer’s time zone.
  • If the time zone is not specified in the date/time string parameter, ColdFusion MX does not adjust the time value.
When developing an application, Macromedia recommends that you evaluate the entered time string for a time zone setting and, if necessary, change your application to adjust the value. You can use a cfcatch block to do this; for more information, see LSParseDateTime() and "CFCATCH variables" in CFML Reference.
If you use the IBM JRE version 1.3.0 with ColdFusion MX, LSParseDateTime("Quarta-feira, 23 de Janeiro de 2002 12h34min56s PST") fails when passing the month “Janeiro”. The following code works with the SUN JRE.

Note: The date pivot point for calculating the century in a two-digit year has changed from ColdFusion 5, affecting the results from date functions. For more information, see Date pivot point for two-digit years.

For more information, see CFML Reference for the relevant function.


Other locale-specific changes

Following are other locale-specific issues that could cause an incompatibility in your ColdFusion 5 applications:

  • For the Japanese version, sort functions such as ListSort() and ArraySort() return items in a slightly different order in ColdFusion MX than they do in the Japanese version of ColdFusion 5. This is because ColdFusion MX sorts characters by their Unicode char number, and the Japanese version of ColdFusion 5 sorts characters by their shift_jis char number.
  • The format for how decimal numbers appear in a browser depends on the system locale of the computer that is hosting ColdFusion MX, not on the locale of ColdFusion MX. For example, if you run the English version of ColdFusion 5 on a computer whose system locale is set to German or French, the decimal point displays as a comma, not a period. ColdFusion 5 displays a period for the decimal point, regardless of the system locale.
  • GetLocale() checks if the locale was explicitly set; for example, from Setlocale(). If not, ColdFusion MX gets the default locale for the operating system from the Java Virtual Machine (JVM). If the operating system has no set locale, or if ColdFusion MX does not support the operating system’s default locale, GetLocale returns en_US “English (US)”. (ColdFusion MX sets the locale in the JVM to en_US “English (US)”; this value persists until the server is restarted or the value is reset with the SetLocale function. This setting does not affect anything but ColdFusion MX.)


Other changes

This section describes other changes between ColdFusion 5 and ColdFusion MX.


Character encoding

ColdFusion MX uses the UTF-8 character set encoding as its default encoding. ColdFusion 5 used the ISO-8859-1 character set encoding. This can affect the way that characters in the range 128–255 are displayed in the browser. To restore the ColdFusion 5 default encoding, place the following cfcontent tag in your page (or in the application’s Application.cfm page):

<cfcontent type="text/html; charset=ISO-8859-1">

Note: UTF-8 (USC Transformation Format, where USC is the Universal Character Set) enables computers to handle both ASCII and Unicode. Unicode (Unicode Worldwide Character Standard) is a system of setting up binary codes for text or script characters, so that the characters from the principal written languages of the world can be displayed and processed.


Advanced Security

ColdFusion MX provides a new and easy way for you to build user authentication and roles-based security into your applications. However, it is based on a completely different security model than ColdFusion 5. Also, ColdFusion MX no longer includes a licensed version of Netegrity Siteminder. Therefore, any existing Advanced Security code--including the cfauthenticate and cfimpersonate tags, and the authenticatedContext(), authenticatedUser(), isAuthenticated(), isProtected(), and isAuthorized() functions--no longer works in ColdFusion MX. These tags and functions are obsolete in ColdFusion MX.

For more information about application security, see Developing ColdFusion MX Applications with CFML.


SNMP support

ColdFusion MX no longer supports Simple Network Management Protocol (SNMP) for monitoring ColdFusion applications from enterprise management systems.


Variables

Following are changes to variables in ColdFusion MX:

  • You can no longer use a dot (.) in a variable name, because ColdFusion MX supports the dot notation as a dot operator to create a struct. For example, last.name creates a struct called last with a key called name, instead of creating a simple variable whose name has a period in it.

    • To work around this, use underscores in variable names instead.

  • The following cfcatch variables have changed: Message, NativeErrorCode, and SQLState. For more information, see cfcatch in CFML tags and attributes.


Operators

Following are changes in operands between ColdFusion 5 and ColdFusion MX:

  • Exponent results differ; for example, ColdFusion 5 returns an error for 0 ^ 3, and ColdFusion MX only returns “1”.
  • ColdFusion MX supports the dot notation as a dot operator. For example, if your ColdFusion 5 application has a variable called last.name, ColdFusion MX reads this code and creates a struct called last with a key called name.

    • In addition, ColdFusion MX does not create keys with dots in them like ColdFusion 5 does, but instead creates cascading structs with non-dotted names. For example, ColdFusion 5 interprets a.b.c="foo" to be a["b.c"]="foo", whereas ColdFusion MX interprets it to be a["b"]["c"]="foo".


CFML data types

ColdFusion MX preserves the case of a struct key, whereas ColdFusion 5 sets every struct key to uppercase. However, you cannot use different case to create more than one key. For example, the following code produces one key, not two:

x.Foo = 1;
x.FOO = 2;

For best results, use consistent case for struct key names.


COM objects

ColdFusion MX uses the Java Native Interface (JNI) to call COM objects, which results in slower performance than in ColdFusion 5. How much slower depends on the application and COM, but in the Macromedia tests of the same code, ColdFusion 5 completed in 50 milliseconds and ColdFusion MX completed in 2-3 seconds.


Template handlers

The Runtime service in Windows has been re-implemented in ColdFusion MX so that you can specify a template handler in the ColdFusion Administrator (Settings page). (A template handler is template to execute when the ColdFusion application server cannot find a requested template.) However, you must specify a template handler as a path that is relative to the web root directory, such as \missing.cfm for the file web_root\missing.cfm. Do not use a full path.


Case in forms

Unlike ColdFusion 5, ColdFusion MX preserves the case of field names submitted by forms, instead of forcing them to uppercase. Like ColdFusion 5, ColdFusion MX ignores case when evaluating field names (for example, #form.myfield# is the same as #FORM.MYFIELD#). However, you should change templates that use Find() or ListFind() to search through the Form.Fieldnames variable, to use case-insensitive equivalents.


Objects for date/time

ColdFusion MX no longer strips milliseconds off of date/time objects; to do this, use the date formatting functions.


Date pivot point for two-digit years

When ColdFusion processes a date that has does not include the century, ColdFusion determines the century. To do this, ColdFusion compares the date to when it processes the date. With a few exceptions, ColdFusion MX uses 20 as the date pivot point for calculating the century in a two-digit year. ColdFusion 5 uses 29.

Note: The following locales use 28 as the date pivot point instead of 20: English(Australian), English(New Zealand), German(Austrian), German(Standard), German (Swiss), Portuguese(Brazilian), Portuguese(Standard), and Swedish. Macromedia has confirmed this inconsistency using the SUN JRE version 1.4 and the IBM JRE version 1.3.0.

So in ColdFusion MX, if the date is within 80 years before and 20 years after the date when it processes the date, then ColdFusion MX returns the date with the current century. Otherwise, it returns the previous century. In ColdFusion 5, if the date is within 71 years before and 29 years after the date when it processes the date, then ColdFusion 5 returns the current century. Otherwise, it returns the previous century. This can cause incompatible results. For example, LSParseDateTime("25-12-13 22:10:15") returns a year of 1925 in ColdFusion MX, and 2025 in ColdFusion 5.

Note: Results might differ, depending on your Java Runtime Environment (JRE). This information reflects tests on the SUN JRE version 1.4 and the IBM JRE version 1.3.0. Macromedia has also tested using the SUN JRE version 1.3.1_01; however, many of these tests have failed on locales other than English(US).

For more information, see the Java documentation for the java.text.SimpleDateFormat class, at http://java.sun.com/j2se/1.3/docs/api/index.html.


Request variable

ColdFusion MX no longer supports the RequestTimeout attribute in the URL. For pages expecting the RequestTimeout attribute in the URL, add the following tag:

<cfsetting RequestTimeout = "#URL.RequestTimeout#">

For more information, see the “Variables and Reserved Words” chapter of CFML Reference.


Definition of pi

ColdFusion MX and ColdFusion 5 define pi with slightly different precision. Therefore, you might obtain slightly different results between the two for trigonometric functions such as sin, cos, and tan at the boundaries (0, 90, 180, 270, ... degrees).


Null values

ColdFusion 5 converted all null values to an empty string (“ ”). ColdFusion MX preserves null values, but converts them to an empty string when you use them as simple values.


thisTag scope

In ColdFusion 5, you can change system values in the thisTag scope that persist throughout the execution of the tag. This is fixed in ColdFusion MX; it throws an exception if you try to set thisTag.hasendtag or thisTag.executionmode.


Caching

In ColdFusion MX, in the Caching page of the ColdFusion Administrator, the Template Cache Size (Number of Templates) option displays the number of templates in the cache. In ColdFusion 5, it displays the size of the cached templates in kilobytes.


Log files

ColdFusion MX does not support the following ColdFusion 5 log files:

  • executive.log
  • remote.log
  • proxy.log
  • cfadmin.log
  • install.log
  • server.stdout
  • rdsservice.stdout


Tag and function examples

This section provides remedies for some of the compatibility issues listed in CFML tags and attributes and CFML functions and variables.

Note: For the most current information on ColdFusion MX compatibility, see the Support section of the Macromedia website (http://www.macromedia.com/support).


Using cfregistry in ColdFusion MX

The cfregistry tag is deprecated for UNIX and Linux platforms. Therefore, you must remove it on UNIX-based versions of ColdFusion to avoid compatibility problems when migrating to a later version of ColdFusion MX.

As an alternative, you can use the store variables in the following scopes:

  • Client
  • Text file
  • Encoded text file
  • Database
  • LDAP server

In Windows, you can continue to store client variables in the registry as in ColdFusion 5. However, you should not use the cfregistry tag to read ColdFusion server settings from the registry, such as the mail root and information about Verity collections and scheduled tasks, because much of this information is no longer stored in the registry, or it is in a different location in the registry. The ColdFusion server settings that are stored in the registry are subject to change. Therefore, you should not rely on registry keys that ColdFusion creates to store its system settings.

Following are two common examples of using the cfregistry tag in ColdFusion 5 that are not compatible with ColdFusion MX.


Incompatible example

In ColdFusion 5, the following sample code checks if a Verity collection exists, and if not, creates one in the appropriate directory relative to the installation path. In ColdFusion MX, this sample code throws an error, because ColdFusion MX does not store information about Verity collections and the installation directory in the registry.

<CFREGISTRY ACTION = "GETALL"
   Branch = "HKEY_LOCAL_MACHINE\SOFTWARE\Allaire\ColdFusion\CurrentVersion\
Collections"
   Type = "KEY"
   Name = "Collections">
<CFSET CollectionFound = 'No'>
<CFLOOP QUERY = "Collections">
   <CFIF Collections.Entry IS request.datasource>
      <CFSET CollectionFound = 'Yes'>
   </CFIF>
</CFLOOP>
<CFIF CollectionFound IS 'No'>
<!--- Create the collection --->
   <CFREGISTRY ACTION = "GET"
      Branch = "HKEY_LOCAL_MACHINE\SOFTWARE\Allaire\ColdFusion\CurrentVersion\
Collections"
      Entry = "RootDirectory"
      Type = "STRING"
      Variable = "CFRootDir">
   <CFIF Server.OS.Name IS NOT "UNIX">
      <CFSET CollectionPath = "#CFRootDir#\Verity\Collections\">
   <CFELSE>
      <CFSET CollectionPath = "#CFRootDir#/verity/collections/">
   </CFIF>
      <CFCOLLECTION Action = "CREATE"
         Collection = "#request.datasource#"
         Path = "#CollectionPath#"
         Language = "english">
</CFIF>


Compatible example

In ColdFusion MX, you cannot retrieve a list of Verity collections that are registered by ColdFusion or the K2 Server using the registry. Instead, use cfcollection with action=“list", perform a Query of Queries on the queryResult that is specified in the name attribute of cfcollection, and use cfdump to display the collections. Following is sample code to accomplish these tasks:

<cfcollection action = "list" name = "verity" >
<cfoutput>List of all known verity collections.<br><br></cfoutput>
<CFDUMP var = "#verity#">
<br>
<cfoutput>Searching for a specific collection by name.<br><br></cfoutput>
<cfquery name = "qoq" dbtype = "query">
select * from verity where verity.name = 'test_db_neo'
</cfquery>
<br>
<CFDUMP var = "#qoq#">

This returns a table of every collection that is registered by ColdFusion or the K2 Server. The table has the following columns:

  • Name The name of the CF registered collection or the alias collection name for the K2 Server registered collection. ColdFusion MX saves the K2 Server registered collection information, so it is available even when the K2 Server is not running.
  • Registered “CF” if the collection is registered by ColdFusion, or “K2” if the collection is registered by the K2 Server.
  • Path The path to the collection. If the collection is external or registered by the K2 Server, the path includes the collection name.
  • Mapped (CF collections only) “YES” or “NO” if the collection is mapped or not.
  • External (CF collections only) “YES” or “NO” if the collection is external or not.
  • Language (CF collections only) The language used by the collection.
  • Online (CF collections only) “YES” or “NO” if the collection is available for searching or not.


Incompatible example

The following example to retrieve ColdFusion mappings throws an error because ColdFusion MX does not store ColdFusion mappings in the registry.

<cfregistry action = "get"
 branch = "HKEY_LOCAL_MACHINE\SOFTWARE\Allaire\ColdFusion\CurrentVersion\
Templates"
 entry = "/cfdao/" type = "String" variable = "RegValue">
<cfif isdefined("regvalue")>
    <cfset request.cfdao_mappeddir = "#regvalue#">
<cfelse>
   <cfoutput>
   Please create a CF Mapping named cfdao which points to your cfdao files before
trying to run this template.
   </cfoutput>
   <cfabort>
</cfif>
<cfinclude template = "/cfdao/dao_application.cfm">


Compatible example

To work around this, you can include error handling in your templates that would notify the system administrator if a cfinclude failed due to a missing mapping. In the event of a missing mapping, the system administrator must create it in the ColdFusion Administrator.

For more information on performing registry operations in ColdFusion MX, see cfregistry in the CFML Reference.


Using ListSort() in ColdFusion MX

When sorting with textnocase in a descending order, ColdFusion 5 and ColdFusion MX return the results in a different order. However, both are correct because in a textnocase sort, “apple” is equal to “APPLE”.

In ColdFusion MX, a descending textnocase sort returns the elements in the exact reverse order as in an ascending textnocase sort. This is different than in ColdFusion 5.

The following code produces different results in ColdFusion MX than in ColdFusion 5:

<cfset list = "orange,Orange,apple">
<cfset listAsc = ListSort(#list#, "textnocase", "asc")>
<cfset listDesc = ListSort(l#list#, "textnocase", "desc")>
<cfdump var = #listAsc#>
<cfdump var = #listDesc#>

This code produces the following results for ascending and descending sort operations in ColdFusion 5 and ColdFusion MX:

Sort order | ColdFusion 5 results | ColdFusion MX results
Ascending (listAsc) | apple, orange,Orange | apple,orange,Orange
Descending (listDesc) | orange, Orange, apple | Orange,orange,apple

For more information, see ListSort() in CFML Reference.


Using the cfindex tag in ColdFusion MX

To populate a collection with the contents of the query results, you can now use the cfindex tag with the query attribute and type = "file" or type = "path", for all actions that require information from the key attribute. You can also still use type = “custom”.

When you use type = "file" or type = "path" with a query, the action attribute queries to get filenames or file paths from the key attribute, and passes the query results to its actions. The actions use the filenames or file paths to execute their code.

The following table shows a sample database for an application on a Windows server:

BookID | URL | Title | Description
bookid1 | url1 | title1 | description1
bookid2 | url2 | title2 | description2
bookid3 | url3 | title3 | description3
file | http://localhost/cfdocs/snippets | title4 | c:\inetpub\wwwroot\cfdocs\snippets\file.cfm
path1 | http://localhost/cfdocs/snippets/ | title5 | c:\inetpub\wwwroot\cfdocs\snippets\
path2 | http://localhost/cfdocs/cfmlsyntaxcheck | title6 | c:\inetpub\wwwroot\cfdocs\cfmlsyntaxcheck

You can populate a collection using either of the following scripts:

  • Populate the snippets collection with files specified in the description column of the database, as shown in the following example:
    • <CFQUERY NAME = "bookquery"
DATASOURCE = "book">
SELECT * FROM book where bookid='file'
</CFQUERY>

<CFOUTPUT QUERY = "bookquery">
#url#,#description# <BR>
<cfindex collection = "snippets" action = "update" type = "file"
query = "bookquery" key = "description" URLPath = "url">
</CFOUTPUT>
  • Populate the snippets collection with paths specified in the description column of the database, as shown in the following example:
    • <CFQUERY NAME="bookquery"
DATASOURCE="book">
SELECT * FROM book where bookid='path1' or bookid='path2'
</CFQUERY>
<CFOUTPUT QUERY="bookquery">
#url#,#description# <BR>
<cfindex collection="snippets" action="update"
type="path" query="bookquery" key="description" URLpath="url" >
</CFOUTPUT>

Previous


About This Book

CFML Reference is your primary ColdFusion Markup Language (CFML) reference. Use this book to learn about CFML tags and functions, ColdFusion expressions, and using JavaScript objects for WDDX in Macromedia ColdFusion MX. It also provides detailed references for Java and C++ CFX interfaces.

Contents
  • Developer resources
  • About Macromedia ColdFusion MX documentation
  • Getting answers
  • Contacting Macromedia
Next


Developer resources

Macromedia, Inc. is committed to setting the standard for customer support in developer education, documentation, technical support, and professional services. The Macromedia website is designed to give you quick access to the entire range of online resources. The following table shows the locations of these resources:

Resource | Description | URL
Macromedia website | General information about Macromedia products and services | http://www.macromedia.com
Information on ColdFusion | Detailed product information on ColdFusion and related topics | http://www.macromedia.com/coldfusion
Macromedia ColdFusion Support Center | Professional support programs that Macromedia offers | http://www.macromedia.com/support/coldfusion
ColdFusion Online Forum | Access to experienced ColdFusion developers through participation in the Online Forums, where you can post messages and read replies on many subjects relating to ColdFusion | http://webforums.macromedia.com/coldfusion/
Installation Support | Support for installation-related issues for all Macromedia products | http://www.macromedia.com/support/email/isupport
Training | Information about classes, on-site training, and online courses offered by Macromedia | http://www.macromedia.com/support/training
Developer Resources | All the resources that you need to stay on the cutting edge of ColdFusion development, including online discussion groups, Knowledge Base, technical papers, and more | http://www.macromedia.com/desdev/developer/
Reference Desk | Development tips, articles, documentation, and white papers | http://www.macromedia.com/v1/developer/TechnologyReference/index.cfm
Macromedia Alliance | Connection with the growing network of solution providers, application developers, resellers, and hosting services creating solutions with ColdFusion | http://www.macromedia.com/partners/


Variables and Reserved Words

This chapter lists ColdFusion scope variables and reserved words.

Contents
  • Scope-specific built-in variables
  • ColdFusion tag-specific variables
  • CGI Environment variables
Next


Scope-specific built-in variables

ColdFusion returns variables, such as those returned in a cfdirectory or cfftp operation. A variable is usually referenced by scoping it according to its type: naming it according to the code context in which it is available; for example, Session.varname, or Application.varname.

You use the cflock tag to limit the scope of CFML constructs that modify shared shared data structures, files, and CFXs, to ensure that modifications occur sequentially. For more information, see cflock, and Developing ColdFusion MX Applications with CFML.


Variable scope

ColdFusion supports the Variables scope. Unscoped variables created with the cfset tag acquire the Variables scope by default. For example, the variable created by the statement <CFSET linguist = Chomsky> can be referenced as #Variables.linguist#


Caller scope

History

New in ColdFusion MX: The Caller scope is accessible as a structure. (In earlier releases, it was not.)


Client variables

The following client variables are read-only:

Client.CFID
Client.CFToken
Client.HitCount
Client.LastVisit
Client.TimeCreated
Client.URLToken


Server variables

Use the Server prefix to reference server variables, as follows:

Server.ColdFusion.ProductName
Server.ColdFusion.ProductVersion
Server.ColdFusion.ProductLevel
Server.ColdFusion.SerialNumber
Server.ColdFusion.SupportedLocales
Server.OS.Name
Server.OS.AdditionalInformation
Server.OS.Version
Server.OS.BuildNumber


Application and session variables

To enable application and session variables, use the cfapplication tag. Reference them as follows:

Application.myvariable
Session.myvariable

To ensure that modifications to shared data occur in the intended sequence, use the cflock tag. For more infomation, see cflock.

The predefined application and session variables are as follows:

Application.ApplicationName
Session.CFID
Session.CFToken
Session.URLToken


Custom tag variables

A ColdFusion custom tag returns the following variables:

ThisTag.ExecutionMode
ThisTag.HasEndTag
ThisTag.GeneratedContent
ThisTag.AssocAttribs[index]

A custom tag can set a Caller variable to provide information to the caller. The Caller variable is set as follows:

<cfset Caller.variable_name = "value">

The calling page can access the variable with the cfoutput tag, as follows:

<cfoutput>#Caller.variable_name#</cfoutput>


Request variable

Request variables store data about the processing of one page request. Request variables store data in a structure that can be passed to nested tags, such as custom tags, and processed once.

To provide information to nested tags, set a Request variable, as follows:

<CFSET Request.field_name1 = "value">
<CFSET Request.field_name2 = "value">
<CFSET Request.field_name3 = "value">
...

Each nested tag can access the variable with the cfoutput tag, as follows:

<CFOUTPUT>#Request.field_name1#</CFOUTPUT>


Form variable

ColdFusion supports the Form variable FieldNames. FieldNames returns the names of the fields on a form. You use it on the action page associated with a form, as follows:

Form.FieldNames


ColdFusion tag-specific variables

Some ColdFusion tags return data as variables. For example, the cffile tag returns file size information in the FileSize variable, referenced as CFFILE.FileSize.

The following tags return data that can be referenced in variables:

cfcatch
cfdirectory
cferror
cffile
cfftp
cfhttp
cfindex
cfldap
cfmail
cfpop
cfquery
cfregistry
cfsearch
cfstoredproc


ColdFusion query variables

A ColdFusion tag that returns a query object supports the following variables, where queryname is the value of the name attribute:

queryname.CurrentRow
queryname.RecordCount
queryname.ColumnList


CFCATCH variables

Within a cfcatch block, the active exception properties can be accessed as the following variables:

CFCATCH.Type
CFCATCH.Message
CFCATCH.Detail
CFCATCH.ErrNumber
CFCATCH.NativeErrorCode
CFCATCH.SQLState
CFCATCH.LockName
CFCATCH.LockOperation
CFCATCH.MissingFileName
CFCATCH.TagContext
CFCATCH.ErrorCode
CFCATCH.ExtendedInfo


CFDIRECTORY variables

The cfdirectory tag, with action=list, returns a query object as follows, where queryname is the name attribute value:

queryname.Name
queryname.Size
queryname.Type
queryname.DateLastModified
queryname.Attributes
queryname.Mode


CFERROR variables

When cferror generates an error page, the following error variables are available if type="request", "exception", or "monitor".

Error.Diagnostics
Error.MailTo
Error.DateTime
Error.Browser
Error.GeneratedContent
Error.RemoteAddress
Error.HTTPReferer
Error.Template
Error.QueryString

The following error variables are available if type="validation".

Error.ValidationHeader
Error.InvalidFields
Error.ValidationFooter

Any cfcatch variable that applies to exception type can be accessed within the Error scope, as follows:

Error.Type
Error.Message
Error.Detail
Error.ErrNumber
Error.NativeErrorCode
Error.SQLState
Error.LockName
Error.LockOperation
Error.MissingFileName
Error.TagContext
Error.ErrorCode
Error.ExtendedInfo

Note: You can substitute the prefix CFERROR for Error, if type = "Exception" or "Monitor"; for example, CFERROR.Diagnostics, CFERROR.Mailto or CFERROR.DateTime.


CFFILE ACTION=Upload variables

File variables are read-only. Use the CFFILE prefix to reference file variables; for example, CFFILE.ClientDirectory. The File prefix is deprecated in favor of the CFFILE prefix.

CFFILE.AttemptedServerFile
CFFILE.ClientDirectory
CFFILE.ClientFile
CFFILE.ClientFileExt
CFFILE.ClientFileName
CFFILE.ContentSubType
CFFILE.ContentType
CFFILE.DateLastAccessed
CFFILE.FileExisted
CFFILE.FileSize
CFFILE.FileWasAppended
CFFILE.FileWasOverwritten
CFFILE.FileWasRenamed
CFFILE.FileWasSaved
CFFILE.OldFileSize
CFFILE.ServerDirectory
CFFILE.ServerFile
CFFILE.ServerFileExt
CFFILE.ServerFileName
CFFILE.TimeCreated
CFFILE.TimeLastModified


CFFTP error variables

When you use the cfftp stoponerror attribute, these variables are populated:

CFFTP.Succeeded
CFFTP.ErrorCode
CFFTP.ErrorText


CFFTP ReturnValue variable

Some cfftp file and directory operations provide a return value, in the variable CFFTP.ReturnValue. Its value is determined by the results of the action attribute. When you specify any of the following actions, cfftp returns a value:

GetCurrentDir
GetCurrentURL
ExistsDir
ExistsFile
Exists


CFFTP query object columns

When you use the cfftp tag with the listdir action, cfftp returns a query object, where queryname is the name attribute value, and row is the row number of each file or directory entry:

queryname.Name[row]
queryname.Path[row]
queryname.URL[row]
queryname.Length[row]
queryname.LastModified[row]
queryname.Attributes
queryname.IsDirectory
queryname.Mode


CFHTTP variables

A cfhttp get operation can return text and binary files. Files are downloaded and the contents stored in a variable or file, depending on the MIME type, as follows:

CFHTTP.FileContent
CFHTTP.MimeType
CFHTTP.Header
CFHTTP.ResponseHeader[http_hd_key]
CFHTTP.StatusCode


CFLDAP variables

The cfldap action=query tag returns information about the LDAP query, as follows:

queryname.CurrentRow
queryname.RecordCount
queryname.ColumnList


CFPOP variables

The cfpop tag returns the following result columns, depending on the action attribute value and the use of other attributes, such as attachmentpath, where queryname is the name attribute value:

queryname.Date
queryname.From
queryname.Body
queryname.Header
queryname.MessageNumber
queryname.ReplyTo
queryname.Subject
queryname.CC
queryname.To
queryname.CurrentRow
queryname.RecordCount
queryname.ColumnList
queryname.Attachments
queryname.AttachmentFiles


CFQUERY and CFSTOREDPROC variables

The cfquery tag returns information about the query in this variable:

CFQUERY.ExecutionTime

The cfquery tag uses the query name to scope the following data about the query:

queryname.CurrentRow
queryname.RecordCount
queryname.ColumnList

The cfstoredproc tag returns the following variables:

CFSTOREDPROC.ExecutionTime
CFSTOREDPROC.StatusCode


CFREGISTRY variables

The cfregistry tag returns a query record set that you can reference after executing the GetAll action, as follows, where queryname is the name attribute value:

queryname.Entry
queryname.Type
queryname.Value


CFSEARCH variables

A cfsearch operation returns the following variables, where searchname is the name attribute value:

searchname.URL
searchname.Key
searchname.Title
searchname.Score
searchname.Custom1 and Custom2
searchname.Summary
searchname.RecordCount
searchname.CurrentRow
searchname.RecordsSearched
searchname.ColumnList


Standard CGI variables

This section lists the CGI 1.1 variables that some web servers create when a CGI script is called.

The CGI variables that are available for your use vary with the web server and configuration. Some of the following variables may not be available.


Request

CGI.AUTH_TYPE
CGI.CONTENT_LENGTH
CGI.CONTENT_TYPE
CGI.PATH_INFO
CGI.PATH_TRANSLATED
CGI.QUERY_STRING
CGI.REMOTE_ADDR
CGI.REMOTE_HOST
CGI.REMOTE_USER
CGI.REQUEST_METHOD
CGI.SCRIPT_NAME


Server

CGI.GATEWAY_INTERFACE
CGI.SERVER_NAME
CGI.SERVER_PORT
CGI.SERVER_PROTOCOL
CGI.SERVER_SOFTWARE


Client

CGI.CERT_ISSUER
CGI.CERT_SUBJECT
CGI.CLIENT_CERT_ENCODED
CGI.HTTP_ACCEPT
CGI.HTTP_IF_MODIFIED_SINCE
CGI.HTTP_USER_AGENT

The CERT_ISSUER, CERT_SUBJECT, CLIENT_CERT_ENCODED variables are available only when you use client certificates.


CGI Environment variables

When a browser makes a request to a server, the web server and the browser create environment variables. In ColdFusion, these variables are referred to as CGI environment variables. They take the CGI prefix regardless of whether the server uses a server API or CGI to communicate with the ColdFusion Server.

Environment variables contain data about the transaction between the browser and the server, such as the IP Address, browser type, and authenticated username. You can reference CGI environment variables for a given page request anywhere in the page. CGI variables are read-only.

Note: The environment variables available to applications depend on the browser and server software.


Testing for CGI variables

Because some browsers do not support some CGI variables, ColdFusion always returns True when it tests for the existence of a CGI variable, regardless of whether the browser supports the variable. To determine if the CGI variable is available, test for an empty string, as shown in the following example:

<cfif CGI.varname IS NOT "">
   CGI variable exists
<cfelse>
   CGI variable does not exist
</cfif>


CGI server variables

The following table describes common CGI environment variables that the server creates (some of these are not available with some servers):

CGI server variable | Description
SERVER_SOFTWARE | Name and version of the information server software answering the request (and running the gateway). Format: name/version.
SERVER_NAME | Server's hostname, DNS alias, or IP address as it appears in self-referencing URLs.
GATEWAY_INTERFACE | CGI specification revision with which this server complies. Format: CGI/revision.
SERVER_PROTOCOL | Name and revision of the information protocol this request came in with. Format: protocol/revision.
SERVER_PORT | Port number to which the request was sent.
REQUEST_METHOD | Method with which the request was made. For HTTP, this is Get, Head, Post, and so on.
PATH_INFO | Extra path information, as given by the client. Scripts can be accessed by their virtual pathname, followed by extra information at the end of this path. The extra information is sent as PATH_INFO.
PATH_TRANSLATED | Translated version of PATH_INFO after any virtual-to-physical mapping.
SCRIPT_NAME | Virtual path to the script that is executing; used for self-referencing URLs.
QUERY_STRING | Query information that follows the ? in the URL that referenced this script.
REMOTE_HOST | Hostname making the request. If the server does not have this information, it sets REMOTE_ADDR and does not set REMOTE_HOST.
REMOTE_ADDR | IP address of the remote host making the request.
AUTH_TYPE | If the server supports user authentication, and the script is protected, the protocol-specific authentication method used to validate the user.
REMOTE_USER AUTH_USER | If the server supports user authentication, and the script is protected, the username the user has authenticated as. (Also available as AUTH_USER.)
REMOTE_IDENT | If the HTTP server supports RFC 931 identification, this variable is set to the remote username retrieved from the server. Use this variable for logging only.
CONTENT_TYPE | For queries that have attached information, such as HTTP POST and PUT, this is the content type of the data.
CONTENT_LENGTH | Length of the content as given by the client.


CGI client variables

The following table describes common CGI environment variables the browser creates and passes in the request header:

CGI client variable | Description
HTTP_REFERER | The referring document that linked to or submitted form data.
HTTP_USER_AGENT | The browser that the client is currently using to send the request. Format: software/version library/version.
HTTP_IF_MODIFIED_SINCE | The last time the page was modified. The browser determines whether to set this variable, usually in response to the server having sent the LAST_MODIFIED HTTP header. It can be used to take advantage of browser-side caching.


CGI client certificate variables

ColdFusion makes available the following client certificate data. These variables are available when running Microsoft IIS 4.0 or Netscape Enterprise under SSL if your web server is configured to accept client certificates.

CGI client certificate
variable

Description
CERT_SUBJECT
Client-specific information provided by the web server. This data typically includes the client's name, e-mail address, etc. For example:
O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "www.verisign.com/repository/RPA Incorp. by Ref.,LIAB.LTD(c)98", OU = Persona Not Validated, OU = Digital ID Class 1 - Microsoft, CN = Matthew Lund, E = mlund@macromedia.com
CERT_ISSUER
Information about the authority that provided the client certificate. For example:
O = "VeriSign, Inc.", OU = VeriSign Trust Network, OU = "www.verisign.com/repository/RPA Incorp. By Ref.,LIAB.LTD(c)98", CN = VeriSign Class 1 CA Individual Subscriber-Persona Not Validated
CLIENT_CERT_ENCODED
The entire client certificate binary, base-64 encoded. This data is typically of interest to developers,so they can integrate with other software that uses client certificates.

Previous


ColdFusion Tag Summary

This chapter lists ColdFusion Markup Language (CFML) tags by functional category.

Contents
  • New tags, attributes, and values
  • Deprecated tags, attributes, and values
  • Obsolete tags, attributes, and values
  • Rules for embedding comments in CFML code
  • Tag summary
  • Application framework tags
  • Database manipulation tags
  • Data output tags
  • Debugging tags
  • Exception handling tags
  • Extensibility tags
  • File management tags
  • Flow-control tags
  • Forms tags
  • Internet Protocol tags
  • Page processing tags
  • Variable manipulation tags
  • Other tags
Next


New tags, attributes, and values

Tag

Attribute or value
New in this ColdFusion
Server release
cfargument
All
ColdFusion MX
cfcache
timespan attribute
ColdFusion MX

cachedirectory attribute
ColdFusion MX
cfchart
All
ColdFusion MX
cfchartdata
All
ColdFusion MX
cfchartseries
All
ColdFusion MX
cfcollection
list value of action attribute
ColdFusion MX

name attribute
ColdFusion MX
cfcomponent
All
ColdFusion MX
cffunction
All
ColdFusion MX
cfhttp
firstRowAsHeaders attribute
ColdFusion MX

charset attribute
ColdFusion MX
cfimport
All
ColdFusion MX
cfinvoke
All
ColdFusion MX
cfinvokeargument
All
ColdFusion MX
cflogin
All
ColdFusion MX
cfloginuser
All
ColdFusion MX
cflogout
All
ColdFusion MX
cfmail
spoolEnable attribute
ColdFusion MX
cfobject
All
ColdFusion MX
cfobjectcache
All
ColdFusion MX
cfprocessingdirective
pageEncoding attribute
ColdFusion MX
cfproperty
All
ColdFusion MX
cfreturn
All
ColdFusion MX
cfsetting
requestTimeOut attribute
ColdFusion MX
cfthrow
object attribute
ColdFusion MX
cftrace
All
ColdFusion MX
cfxml
All
ColdFusion MX


Deprecated tags, attributes, and values

The following tags, attributes, and attribute values are deprecated. Do not use them in ColdFusion applications. They might not work, and might cause an error, in releases later than ColdFusion MX.

Tag

Attribute or value
Deprecated as of this
ColdFusion Server
release
cfcache
timeout attribute
ColdFusion MX
cffile
attributes attribute value archive
ColdFusion MX

attributes attribute value system
ColdFusion MX

attributes attribute value temporary
ColdFusion MX
cfgraph
All
ColdFusion MX
cfgraphdata
All
ColdFusion MX
cfgridupdate

connectString attribute
ColdFusion MX

dbName attribute
ColdFusion MX

dbServer attribute
ColdFusion MX

dbType attribute
ColdFusion MX

provider attribute
ColdFusion MX

providerDSN attribute
ColdFusion MX
cfindex
external attribute
ColdFusion MX
cfinsert
connectString attribute
ColdFusion MX

dbName attribute
ColdFusion MX

dbServer attribute
ColdFusion MX

dbType attribute
ColdFusion MX

provider attribute
ColdFusion MX

providerDSN attribute
ColdFusion MX
cfldap
filterConfig attribute
ColdFusion MX

filterFile attribute
ColdFusion MX
cflog
date attribute value "No"
ColdFusion MX

thread attribute value "No"
ColdFusion MX

time attribute value "No"
ColdFusion MX
cfquery
connectString attribute
ColdFusion MX

dbName attribute
ColdFusion MX

dbServer attribute
ColdFusion MX

The following dbType attribute values:
  • dynamic
  • ODBC
  • Oracle73
  • Oracle80
  • Sybase11
  • OLEDB
  • DB2
ColdFusion MX
(The value query is valid.)

provider attribute
ColdFusion MX

providerDSN attribute
ColdFusion MX

sql attribute
ColdFusion MX
cfregistry
All, on UNIX only
ColdFusion MX
cfsearch
external attribute
ColdFusion MX
cfservlet
All
ColdFusion MX
cfservletparam
All
ColdFusion MX
cfslider
img attribute
ColdFusion MX

imgStyle attribute
ColdFusion MX

grooveColor attribute
ColdFusion MX
cfstoredproc
connectString attribute
ColdFusion MX

dbName attribute
ColdFusion MX

dbServer attribute
ColdFusion MX

provider attribute
ColdFusion MX

providerDSN attribute
ColdFusion MX
cfupdate
connectString attribute
ColdFusion MX

dbName attribute
ColdFusion MX

dbServer attribute
ColdFusion MX

provider attribute
ColdFusion MX

providerDSN attribute
ColdFusion MX


Obsolete tags, attributes, and values

The following tags, attributes, and attribute values are obsolete. Do not use them in ColdFusion applications. They do not work, and might cause an error, in release later than ColdFusion 5.

Tag

Attribute or value
Obsolete as of this
ColdFusion Server release
cfauthenticate
All
ColdFusion MX
cfimpersonate
All
ColdFusion MX
cfindex
action attribute value optimize
ColdFusion MX
cfinternaladminsecurity
All
ColdFusion MX
This tag did not appear in the CFML Reference.
cfnewinternaladminsecurity
All
ColdFusion MX
This tag did not appear in the CFML Reference.
cfsetting
catchExceptionsByPattern attribute
ColdFusion MX


Rules for embedding comments in CFML code

New in ColdFusion MX: You can embed a CFML comment within the following ColdFusion elements:

  • A start tag
  • A tag
  • A custom tag
  • A function call
  • Variable text that is within pound signs.

ColdFusion ignores the comment. (In earlier releases, comments within these constructs were not allowed.)

The following examples show valid embedded CFML comments:

<cfif true eq true <!--- comment --->>
<cfoutput>myVar: #myVar<!--- comment within pound signs--->#</cfoutput>
#IncrementValue(120<!--- comment next to argument--->)#
<cf__comment_pos_05 <!--- comment within custom-tag brackets --->>
<cfset foo = evaluate("1 + 2<!--- comment --->")>
isDefined(dynamicVariable<!--- comment --->)
#isDefined<!--- comment --->("MyConstruct")#
<cfset myLVar<!--- comment ---> = "myLVar&lt;!--- comment ---&gt;">

The following examples show invalid or erroneous embedded CFML comments:

isDefined("myVariable<!--- no comment within name string --->")
is<!--- no comment within function name --->Defined("myVariable")
<cfout<!--- no comment within tag name --->put "#myVariable#">


Tag summary

ColdFusion Markup Language (CFML) includes a set of tags that you use in ColdFusion pages to interact with data sources, manipulate data, and display output. CFML tag syntax is similar to HTML element syntax.

The following table describes CFML tags.

CFML tag
Category
Description
cfabort
Flow-control tags
Stops the processing of a ColdFusion page at the tag location
cfapplet
Forms tags
Embeds Java applets in a cfform tag
cfapplication
Application framework tags
Defines an application name; activates client variables; specifies client variable storage mechanism
cfargument
Extensibility tags
Creates a parameter definition within a component definition. Defines a function argument.
cfassociate
Application framework tags
Enables subtag data to be saved with a base tag
cfbreak
Flow-control tags
Breaks out of a CFML looping construct
cfcache
Page processing tags
Caches ColdFusion pages
cfcase
Flow-control tags
Used with the cfswitch and cfdefaultcase tags
cfcatch
Exception handling tags,
Flow-control tags
Catches exceptions in ColdFusion pages
cfchart
Data output tags
Generates and displays a chart
cfchartdata
Data output tags
Defines chart data points
cfchartseries
Data output tags
Defines style in which chart data displays
cfcol
Data output tags
Defines table column header, properties
cfcollection
Extensibility tags
Administers Verity collections
cfcomponent
Extensibility tags
Creates and defines a component object
cfcontent
Data output tags,
Page processing tags
Defines content type and filename of a file to be downloaded by current page
cfcookie
Variable manipulation tags
Defines and sets cookie variables, including expiration and security options
cfdefaultcase
Flow-control tags
Receives control if there is no matching cfcase tag value
cfdirectory
File management tags
Performs typical directory-handling tasks from within a ColdFusion application
cfdump
Debugging tags,
Variable manipulation tags
Outputs variables for debugging
cfelse
Flow-control tags
Creates IF-THEN-ELSE constructs
cfelseif
Flow-control tags
Creates IF-THEN-ELSE constructs
cferror
Exception handling tags,
Application framework tags
Displays custom HTML error pages when errors occur
cfexecute
Flow-control tags,
Extensibility tags
Executes developer-specified process on server computer
cfexit
Flow-control tags
Aborts processing of executing CFML tag.
cffile
File management tags
Performs typical file-handling tasks from within ColdFusion application
cfflush
Data output tags,
Page processing tags
Flushes currently available data to client
cfform
Forms tags
Builds input form; performs client-side input validation
cfftp
Forms tags,
Extensibility tags,
Internet Protocol tags
Permits FTP file operations
cffunction
Extensibility tags
Defines function that you build in CFML
cfgrid
Forms tags
Displays tabular grid control, in cfform tag
cfgridcolumn
Forms tags
Used in cfform; defines columns in a cfgrid
cfgridrow
Forms tags
Defines a grid row; used with cfgrid
cfgridupdate
Forms tags
Directly updates ODBC data source from edited grid data
cfheader
Data output tags,
Page processing tags
Generates HTTP headers
cfhtmlhead
Forms tags,
Page processing tags
Writes text and HTML to HEAD section of page
cfhttp
Forms tags,
Internet Protocol tags
Performs GET and POST to upload file or post form, cookie, query, or CGI variable directly to server
cfhttpparam
Forms tags,
Internet Protocol tags
Specifies parameters required for a cfhttp POST operation; used with cfhttp
cfif
Flow-control tags
Creates IF-THEN-ELSE constructs
cfimport
Application framework tags
Imports JSP tag libraries into a CFML page.
cfinclude
Flow-control tags
Embeds references to ColdFusion pages
cfindex
Extensibility tags,
Creates Verity search indexes
cfinput
Forms tags
Creates an input element (radio button, checkbox, text entry box); used in cfform
cfinsert
Database manipulation tags
Inserts records in a data source
cfinvoke
Extensibility tags
invokes component methods from a ColdFusion page or component
cfinvokeargument
Extensibility tags
Passes a parameter to a component method or a web service
cfldap
Forms tags,
Internet Protocol tags
Provides access to LDAP directory servers
cflocation
Flow-control tags
Controls execution of a page
cflock
Application framework tags
Ensures data integrity and synchronizes execution of CFML code
cflog
Data output tags,
Other tags
Writes a message to a log file
cflogin
Extensibility tags
Defines a container for user login and authentication code.
cfloginuser
Extensibility tags
Identifies an authenticated user to ColdFusion.
cflogout
Extensibility tags
Logs the current user out.
cfloop
Flow-control tags
Repeats a set of instructions based on conditions
cfmail
Forms tags,
Internet Protocol tags
Assembles and posts an e-mail message
cfmailparam
Forms tags,
Internet Protocol tags
Attaches a file or adds a header to an e-mail message
cfmodule
Application framework tags
Invokes a custom tag for use in a ColdFusion page
cfobject
Extensibility tags
Creates COM, component, CORBA, Java and web service objects
cfobjectcache
Database manipulation tags
Flushes the query cache
cfoutput
Data output tags
Displays the output of a database query or other operation
cfparam
Variable manipulation tags
Defines a parameter and its default value
cfpop
Forms tags,
Internet Protocol tags
Gets and deletes messages from POP mail server
cfprocessingdirective
Data output tags
Suppresses white space and other output
cfprocparam
Database manipulation tags
Holds parameter information for stored procedure
cfprocresult
Database manipulation tags
Result set name that ColdFusion tags use to access result set of a stored procedure
cfproperty
Extensibility tags
Defines components
cfquery
Database manipulation tags
Passes SQL statements to a database
cfqueryparam
Database manipulation tags
Checks data type of a query parameter
cfregistry
Other tags,
Variable manipulation tags
Reads, writes, and deletes keys and values in a Windows system registry
cfreport
Exception handling tags
Embeds a Crystal Reports report
cfrethrow
Exception handling tags
Rethrows currently active exception
cfreturn
Extensibility tags
Returns results from a component method
cfsavecontent
Variable manipulation tags
Saves generated content inside tag body in a variable
cfschedule
Variable manipulation tags
Schedules page execution; optionally, produces static pages
cfscript
Application framework tags
Encloses a set of cfscript statements
cfsearch
Extensibility tags
Executes searches against data indexed in Verity collections, using cfindex
cfselect
Forms tags
Creates a drop-down list box form element; used in cfform tag
cfset
Variable manipulation tags
Defines a variable
cfsetting
Other tags,
Variable manipulation tags
Defines and controls ColdFusion settings
cfsilent
Data output tags,
Page processing tags
Suppresses CFML output within tag scope
cfslider
Forms tags
Creates slider control; used in cfform
cfstoredproc
Database manipulation tags
Holds database connection information; identifies a stored procedure to execute
cfswitch
Flow-control tags
Evaluates passed expression; passes control to matching cfcase tag
cftable
Data output tags
Builds a table in a ColdFusion page
cftextinput
Forms tags
Puts a one-line text entry box in a form
cfthrow
Exception handling tags,
Flow-control tags
Throws a developer-specified exception
cftrace
Debugging tags
Displays and logs application debugging data
cftransaction
Database manipulation tags
Groups cfquery operations into one transaction; performs rollback processing
cftree
Forms tags
Creates tree control element; used in cfform
cftreeitem
Forms tags
Populates a tree control element in a form; used with cftree
cftry
Exception handling tags,
Flow-control tags
Catches exceptions in ColdFusion pages
cfupdate
Database manipulation tags
Updates rows in a database data source
cfwddx
Extensibility tags
Serializes and de-serializes CFML data structures to XML-based WDDX format
cfxml
Extensibility tags
Creates an XML document object


Application framework tags

cfapplication

cfimport

cfscript

cfassociate

cflock

cferror

cfmodule


Database manipulation tags

cfinsert

cfprocresult

cfstoredproc

cfobjectcache

cfquery

cftransaction

cfprocparam

cfqueryparam

cfupdate


Data output tags

cfchart

cfcontent

cfoutput

cfchartdata

cfflush

cfprocessingdirective

cfchartseries

cfheader

cfsilent

cfcol

cflog

cftable


Debugging tags

cfdump

cftrace


Exception handling tags

cfcatch

cfreport

cfthrow

cferror

cfrethrow

cftry


Extensibility tags

cfchart

cffunction

cfobject

cfchartdata

cfindex

cfproperty

cfchartseries

cfinvoke

cfreport

cfcollection

cfinvokeargument

cfreturn

cfcomponent

cflogin

cfsearch

cfexecute

cfloginuser

cfwddx

cfftp

cflogout

cfxml


File management tags

cfdirectory

cffile

cfftp


Flow-control tags

cfabort

cfexecute

cfrethrow

cfbreak

cfexit

cfswitch

cfcase

cfif

cfthrow

cfdefaultcase

cfinclude

cftry

cfelse

cflocation

cfelseif

cfloop


Forms tags

cfapplet

cfhtmlhead

cfselect

cfform

cfinput

cfslider

cfgrid

cfldap

cftextinput

cfgridcolumn

cfmail

cftree

cfgridrow

cfmailparam

cftreeitem

cfgridupdate

cfpop


Internet Protocol tags

cfftp

cfldap

cfpop

cfhttp

cfmail

cfhttpparam

cfmailparam


Page processing tags

cfcache

cfheader

cfsetting

cfcontent

cfhtmlhead

cfsilent

cfflush

cfinclude


Variable manipulation tags

cfcookie

cfregistry

cfset

cfdump

cfsavecontent

cfsetting

cfparam

cfschedule


Other tags

cflog

cfregistry

Previous


ColdFusion Tags: cfabort--cfloop

This chapter describes ColdFusion Markup Language (CFML) tags. The tags are listed alphabetically.

Next


cfabort

Description

Stops the processing of a ColdFusion page at the tag location. ColdFusion returns everything that was processed before the tag. The tag is often used with conditional logic to stop processing a page when a condition occurs.

Category

Flow-control tags

Syntax

<cfabort
   showError = "error_message">

See also

cfbreak , cfexecute , cfexit , cfif , cflocation , cfloop , cfswitch , cfthrow , cftry

Attributes

Attribute | Req/ Opt | Default | Description
showError | Optional |  | Error to display, in a standard ColdFusion error page, when tag executes.

Usage

When you use the cfabort and cferror tags together, the cfabort tag halts processing immediately; the cferror tag redirects output to a specified page.

If this tag does not contain a showError attribute value, processing stops when the tag is reached and ColdFusion returns the page contents up to the line that contains the cfabort tag.

When you use this tag with the showError attribute, but do not define an error page using cferror, page processing stops when the cfabort tag is reached. The message in showError displays to the client.

When you use this tag with the showError attribute and an error page using cferror, ColdFusion redirects output to the error page specified in the cferror tag.

Example

<!--- this example shows the use of cfabort to stop processing.
In the second example, where cfabort is used, the result never displays --->

<h3>Example A: Let the instruction complete itself</h3>
<!--- first, set a variable --->
<cfset myVariable = 3>
<!--- now, perform a loop that increments this value --->
<cfloop from = "1" to = "4" index = "Counter">
   <cfset myVariable = myVariable + 1>
</cfloop>

<cfoutput>
<p>   The value of myVariable after incrementing through the loop #Counter# times is:
#myVariable#
</cfoutput>

<h3>Example B: Use cfabort to halt the instruction</h3>
<!--- reset the variable and show the use of cfabort --->
<cfset myVariable = 3>
<!--- now, perform a loop that increments this value --->
<cfloop from = "1" to = "4" index = "Counter">
   <!--- on the second time through the loop, cfabort --->
   <cfif Counter is 2>
      <cfabort>
   <!--- processing is stopped, and subsequent operations are not carried out --->
   <cfelse>
   <cfset myVariable = myVariable + 1>
   </cfif>
</cfloop>

<cfoutput>
<p>   The value of myVariable after incrementing through the loop
#counter# times is: #myVariable#
</cfoutput>


cfapplet

Description

This tag references a registered custom Java applet. To register a Java applet, in the ColdFusion Administrator, click Extensions > Java Applets.

Using this tag within a cfform tag is optional. If you use it within cfform, and the method attribute is defined in the Administrator, the return value is incorporated into the form.

Category

Forms tags

Syntax

<cfapplet
   appletSource = "applet_name"
   name = "form_variable_name"
   height = "height_in_pixels"
   width = "width_in_pixels"
   vSpace = "space_above_and_below_in_pixels"
   hSpace = "space_on_each_side_in_pixels"
   align = "alignment_option"
   notSupported = "message_to_display_for_nonJava_browser"
   param_1 = "applet_parameter_name"
   param_2 = "applet_parameter_name"
   param_n = "applet_parameter_name">

See also

cfform , cfobject , cfservlet

History

New in ColdFusion MX: Using this tag within a cfform tag is optional. If you use it within cfform, and the method attribute is defined in the Administrator, the return value of the applet’s method is incorporated into the form.

Attributes

Attribute
Req/Opt
Default
Description
appletSource
Required
Name of registered applet
name
Required
Form variable name for applet
height
Optional
Height of applet, in pixel
width
Optional
Width of applet, in pixels
vSpace
Optional
Space above and below applet, in pixels
hSpace
Optional
Space on left and right of applet, in pixels
align
Optional
Alignment:
  • Left
  • Right
  • Bottom
  • Top
  • TextTop
  • Middle
  • AbsMiddle
  • Baseline
  • AbsBottom
notSupported
Optional
See Description
Text to display if a page that contains a Java applet-based cfform control is opened by a browser that does not support Java or has Java support disabled. For example:
notSupported = "<b>Browser must support Java to view
ColdFusion Java Applets</b>"
Default:
<b>Browser must support Java to<br> view ColdFusion Java Applets!</b>
param_n
Optional
Registered parameter for applet. Specify only to override values for applet in ColdFusion Administrator.

Usage

You can specify the applet method attribute only in the Administrator, Java Applets view. For other attributes, you can accept the default values in the Administrator view, or specify values in this tag and override the defaults.

If Java applet components are stored in a JAR file, enter the file name in the ColdFusion Administrator, Java Applets window, Archive text box.

Example

<p>cfapplet lets you reference custom Java applets that have been
   registered using the ColdFusion Administrator.
<p>To register a Java applet, open the ColdFusion Administrator and
   click "Applets" link under "extensions" section.
<p>This example applet copies text that you type into a form. Type
   some text, and then click "copy" to see the copied text.

<cfform action = "index.cfm">
   <cfapplet appletsource = "copytext" name = "copytext">
</cfform>


cfapplication

Description

Defines the scope of a ColdFusion application; enables and disables storage of Client variables; specifies the Client variable storage mechanism; enables Session variables; and sets Application variable timeouts.

Category

Application framework tags

Syntax

<cfapplication
   name = "application_name"
   clientManagement = "Yes" or "No"
   clientStorage = "datasource_name" or "Registry" or "Cookie"
   setClientCookies = "Yes" or "No"
   sessionManagement = "Yes" or "No"
   sessionTimeout = #CreateTimeSpan(days, hours, minutes, seconds)#
   applicationTimeout = #CreateTimeSpan(days, hours,minutes, seconds)#
   setDomainCookies = "Yes" or "No">

See also

cfassociate , cferror , cflock , cfmodule

History

New in ColdFusion MX: Server, Session, and Application scope variables are stored in memory as structures. In earlier releases, only Session and Application scope variables were stored this way. You cannot access the UDF function scope as a structure.

New in ColdFusion MX: ColdFusion sets the CFTOKEN variable value using this algorithm: if the registry key UUIDToken is a non-zero value, ColdFusion uses a number constructed from the UUID plus a random number. Otherwise, ColdFusion sets the CFTOKEN variable default value using a positive random integer. (In earlier releases, ColdFusion always used a number constructed from the UUID plus a random number.)

Attributes

Attribute
Req/Opt
Default
Description
name
See Description
Name of application. Up to 64 characters.
For Application and Session variables: Required.
For Client variables: Optional
clientManagement
Optional
No
  • Yes: enables client variables
  • No
clientStorage
Optional
registry
How client variables are stored:
  • datasource_name: in ODBC or native data source. You must create storage repository in the Administrator.
  • registry: in the system registry.
  • cookie: on client computer in a cookie. Scalable. If client disables cookies in the browser, client variables do not work.
setClientCookies
Optional
Yes
  • Yes: enables client cookies
  • No: ColdFusion does not automatically send CFID and CFTOKEN cookies to client browser; you must manually code CFID and CFTOKEN on the URL for every page that uses Session or Client variables.
sessionManagement
Optional
No
  • Yes: enables session variables
  • No
sessionTimeout
Optional
Specified in Variables page of ColdFusion Administrator
Lifespan of session variables. CreateTimeSpan function and values in days, hours, minutes, and seconds, separated by commas.
applicationTimeout
Optional
Specified in Variables page of ColdFusion Administrator
Lifespan of application variables. CreateTimeSpan function and values in days, hours, minutes, and seconds, separated by commas.
setDomainCookies
Optional
No
  • Yes: Sets CFID and CFTOKEN cookies for a domain (not a host). Required, for applications running on clusters.
  • No

Usage

This tag is typically used in the Application.cfm file, to set defaults for a ColdFusion application.

This tag enables application variables, unless they are disabled in the ColdFusion Administrator. The Administrator setting also overrides the sessionManagement attribute. For more information, see Administering ColdFusion MX.


Server, application, and session variables

When you display, set, or update variables in the server, application, and session scopes, use the cflock tag with the scope attribute set to the following value:

  • For server variables, specify "server"
  • For application variables, specify "application"
  • For session variables, specify "session"

For information about locking scopes, see cflock.

If ColdFusion is running on a cluster, you must specify clientStorage = "cookie" or a data source name; you cannot specify "registry".

If you use this tag to activate the Application and Client scopes, ColdFusion saves the application name as a key, whose maximum length is 64 characters. If an application name is longer than this, the client store fails during database processing.

The CFTOKEN variable is 8 bytes in length. Its range is 10000000 --99999999.

Example

<!--- This example shows how to use cflock to guarantee consistent data
updates to variables in Application, Server, and Session scopes. --->
   <h3>cfapplication Example</h3>
   <p>cfapplication defines scoping for a ColdFusion application and
enables or disables the storing of application and/or sessionvariables.
This tag is placed in a special file calledApplication.cfm that is run
before any other CF page in a directory where the Application.cfm file
appears.

   <cfapplication name = "ETurtle"
      sessionTimeout = #CreateTimeSpan(0, 0, 0, 60)#
      sessionManagement = "Yes">
   <!---    Initialize session and application variables used by E-Turtleneck.
Use session scope for session variables. --->
   <cflock scope = "Session" timeout = "30" type = "Exclusive">
      <cfif NOT IsDefined("session.size")>
         <cfset session.size = "">
      </cfif>
      <cfif NOT IsDefined("session.color")>
         <cfset session.color = "">
      </cfif>
   </cflock>
   <!--- Use the application scope for the application variable. This variable
keeps track of total number of turtlenecks sold. --->
   <cflock scope = "Application" timeout = "30" type = "Exclusive">
      <cfif NOT IsDefined("application.number")>
         <cfset application.number = 1>
      </cfif>
   </cflock>
   <cflock scope = "Application" timeout = "30" type = "readOnly">
      <cfoutput>
      E-Turtleneck is proud to say that we have sold #application.number#
      turtlenecks to date.
      </cfoutput>
  </cflock>
<!--- End of Application.cfm --->


cfargument

Description

Creates a parameter definition within a component definition. Defines a function argument. Used within a cffunction tag.

Category

Extensibility tags

Syntax

<cfargument
   name=”...”
   type=”...”
   required=”...”
   default=”...”
   ...>

See also

cfcomponent , cffunction , cfinvoke , cfinvokeargument , cfobject , cfproperty , cfreturn

Attributes

Attribute
Req/Opt
Default
Description
name
Required
String; an argument name.
type
Optional
any
String; a type name; data type of the argument.
  • any
  • array
  • binary
  • boolean
  • date
  • guid
  • numeric
  • query
  • string
  • struct
  • uuid
  • variableName
  • a component name
If the value is not a recognized type, ColdFusion processes it as a component name.
required
Optional
no
Whether the parameter is required in order to execute the component method.
  • yes
  • no
default
Optional
A type; if no argument is passed, specifies a default argument value.
If this attribute is present, the required attribute must be set to "no" or not specified.

Usage

This tag must be positioned before any other tags within the cffunction tag.

Arguments that are passed when a method is invoked can be accessed from the method body in the following ways:

  • With shorthand syntax: #myargument#
    (This example accesses the argument myargument.)
  • Using the arguments scope as an array: #arguments[1]#
    (This example accesses the first defined argument in the cffunction)
  • Using the arguments scope as a struct: #arguments.myargument#
    (This example accesses the argument myargument in the array)


cfassociate

Description

Allows subtag data to be saved with a base tag. Applies only to custom tags.

Category

Application framework tags

Syntax

<cfassociate
   baseTag = "base_tag_name"
   dataCollection = "collection_name">

See also

cfapplication , cferror , cflock , cfmodule

Attributes

Attribute | Req/Opt | Default | Description
baseTag | Required |  | Base tag name
dataCollection | Optional | AssocAttribs | Structure in which base tag stores subtag data

Usage

Call this tag within a subtag, to save subtag data in the base tag.

When ColdFusion passes subtag attributes back to the base tag, it saves them in a structure whose default name is AssocAttribs. To segregate subtag attributes (in a base tag that can have multiple subtags), specify a structure name, in the DataCollection attribute. The structure is appended to an array whose name is thistag.collectionName.

Within the custom tag code, the attributes passed with the attributeCollection attribute are saved as independent values, with no indication that they are grouped into a structure by the custom tag’s caller.

If an attribute value is explicitly assigned to the attribute name, and is a member of the attributecollection attribute, the explicit value overrides the value in the attributecollection structure.

Example

<!--- Find the context --->
<cfif thisTag.executionMode is "start">
 <!--- Associate attributes --->
 <cfassociate baseTag = "CF_TAGBASE">

 <!--- Define defaults for attributes --->
 <cfparam name = "attributes.happy" default = "Yes">
 <cfparam name = "attributes.sad" default = "No">
...


cfauthenticate

Description

This tag is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML.

History

New in ColdFusion MX: this tag is obsolete. It does not work in ColdFusion MX and later releases.


cfbreak

Description

Used within a cfloop tag. Breaks out of a loop.

Category

Flow-control tags

Syntax

<cfbreak>

See also

cfabort , cfexecute , cfif , cflocation , cfloop , cfswitch , cfthrow , cftry

Example

<!--- This shows the use of cfbreak to exit a loop when a condition is met --->
<!--- select courses; use cfloop to find a condition; then break the loop --->
<!--- check that number is numeric --->
<cfif IsDefined("form.number")>
   <cfif Not IsNumeric(form.number)>
      <cfabort>
      </cfif>
   </cfif>
<cfquery name="GetCourses" datasource="cfsnippets">
   SELECT *
   FROM Courses
   ORDER by Course_Number
</cfquery>
<p> This example uses CFLOOP to cycle through a query to find a value.
(In our example, a list of values corresponding to courses in the Snippets
datasource). When the conditions of the query are met, CFBREAK stops the loop.
<p> Please enter a Course Number, and hit the "submit" button:
<form action="index.cfm" method="POST">
      <select name="courseNum">
   <cfoutput query="GetCourses">
      <option value="#Course_Number#">#Course_Number#
      </cfoutput>
      </select>
   <input type="Submit" name="" value="Search on my Number">
</form>
<!---- if the courseNum variable is not defined, don't loop through the query --->
<cfif IsDefined ("form.courseNum") IS "True">
   <!--- loop through query until value found, then use CFBREAK to exit query--->
   <cfloop query="GetCourses">
      <cfif GetCourses.Course_Number IS form.courseNum>
         <cfoutput>
            <h4>Your Desired Course was found:</h4>
            <pre>#Course_Number# #Descript#</pre>
         </cfoutput>
         <cfbreak>
      <cfelse>
            <br> Searching...
      </cfif>
   </cfloop>
</cfif>


cfcache

Description

Stores a copy of a page on the server and/or client computer, to improve page rendering performance. To do this, the tag creates temporary files that contain the static HTML returned from a ColdFusion page.

Use this tag if it is not necessary to get dynamic content each time a user accesses a page.

You can use this tag for simple URLs and for URLs that contain URL parameters.

Category

Page processing tags

Syntax

<cfcache
   action = "action"
   directory = "directory_name"
   timespan = "value"
   expireURL = "wildcarded_URL_reference"
   username = "username"
   password = "password"
   port = "port_number"
   protocol = "protocol">

See also

cfflush , cfheader , cfhtmlhead , cfsetting , cfsilent

History

New in ColdFusion MX:

  • The timeout and cachedirectory attributes are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.
  • The timespan attribute is new.
  • The default action attribute value, cache, caches a page on the server and the client. (In earlier releases, this option cached a page only on the server.) The default protocol and port values are taken from the current page URL. (In earlier releases, they were "http"and "80", respectively.)
  • This tag can cache pages that depend on session state, including pages that are secured with a ColdFusion login. (In earlier releases, the session state was cleared when caching the page, causing authentication to be lost.)
  • This tag uses a hash() of the URL for the file name to cache a file. (In earlier releases, ColdFusion used the cfcache.map file.)

Attributes

Attribute
Req/Opt
Default
Description
action
Optional
cache
  • cache: server-side and client-side caching.
  • flush: refresh cached page(s).
  • clientcache: browser-side caching only. To cache a personalized page, use this option.
  • servercache: server-side caching only. Not recommended.
  • optimal: same as "cache".
directory
Optional
cf_root/cache
Absolute path of cache directory.
timespan
Optional
Page is flushed only when cfcache action = "flush" is executed
The interval until the page is flushed from the cache.
  • A decimal number of days. For example:
    • - ".25", for one-fourth day (6 hours)
    - "1", for one day
    - "1.5", for one and one half days
  • A return value from the CreateTimeSpan function. For example:
    "#CreateTimeSpan(0, 6, 0, 0)#"
expireURL
Optional
Flush all cached pages
Used with action = "flush". A URL reference. ColdFusion matches it against the mappings in the specified cache directory. Can include wildcards. For example: "*/view.cfm?id=*".
username
Optional
A username. Provide this if the page requires authentication at the web server level.
password
Optional
A password. Provide this if the page requires authentication at the web server level.
port
Optional
The current page port
Port number of the web server from which the URL is requested. In the internal call from cfcache to cfhttp, ColdFusion resolves each URL variable in the page; this ensures that links in the page remain functional.
protocol
Optional
The current page protocol
Protocol that is used to create URL from cache.
  • http://
  • https://

Usage

Use this tag in pages whose content is not updated frequently. Taking this action can greatly improve the performance of your application.

The output of a cached page is stored in a file on the client browser and/or the ColdFusion server. Instead of regenerating and redownloading the output of the page, each time it is requested, ColdFusion uses the cached output. ColdFusion regenerates and downloads the page only when the cache is flushed, as specified by the timespan attribute, or by invoking cfcache action=flush.

To enable a simple form of caching, put a cfcache tag, specifying the timespan attribute, at the top of a page. Each time the specified time span passes, ColdFusion flushes (deletes) the copy of the page from the cache and caches a new copy for users to access.

You can specify client-side caching or a combination of client-side and server-side caching (the default), using the action attribute. The advantage of client-side caching is that it requires no ColdFusion resources; the browser stores pages in its own cache, improving performance. The advantage of combination caching is that it optimizes server performance; if the browser does not have a cache of the page, the server can get data from its own cache. (Macromedia recommends that you do not use server-side only caching. Macromedia recommends that you use combination caching.)

If a page contains personalized content, use the action = "clientcache" option to avoid the possibility of caching a personalized copy of a page for other users.

Debug settings have no effect on cfcache unless the application page enables debugging. When generating a cached file, cfcache uses cfsetting showDebugOutput = "No".

The cfcache tag evaluates each unique URL, including URL parameters, as a distinct page, for caching purposes. For example, the output of http://server/view.cfm?id=1 and the output of http://server/view.cfm?id=2 are cached separately.

The cfcache tag uses the cfhttp tag to get the contents of a page to cache. If there is an HTTP error accessing the page, the contents are not cached. If a ColdFusion error occurs, the error is cached.

Example

<!--- This example produces as many cached files as there are
URL parameter permutations. --->
<cfcache
    timespan="#createTimeSpan(0,0,10,0)#">
<body>

<h3>This is a test of some simple output</h3>
<cfparam name = "URL.x" default = "no URL parm passed" >
<cfoutput>The value of URL.x = # URL.x #</cfoutput>


cfcase

Description

Used with the cfswitch and cfdefaultcase tags.

For more information, see cfswitch.

Category

Flow-control tags


cfcatch

Description

Used with the cftry tag.

For more information, see cftry.

Category

Exception handling tags


cfchart

Description

Generates and displays a chart.

Category

Data output tags, Extensibility tags

Syntax

<cfchart
   format = “flash, jpg, png”
   chartHeight = "integer number of pixels"
   chartWidth = "integer number of pixels"
   scaleFrom = "integer minimum value"
   scaleTo = "integer maximum value"
   showXGridlines = “yes" or "no”
   showYGridlines = “yes" or "no”
   gridlines = "integer number of lines"
   seriesPlacement = "default, cluster, stacked, percent"
   foregroundColor = "Hex value or Web color"
   dataBackgroundColor = "Hex value or Web color"
   borderBackgroundColor = “Hex value or Web color”
   showBorder = "yes" or "no”
   font = “font name”
   fontSize = “integer font size”
   fontBold = “yes" or "no”
   fontItalic = “yes" or "no”
   labelFormat = “number, currency, percent, date”
   xAxisTitle = "title text"
   yAxisTitle = "title text"
   sortXAxis = "yes/no"
   show3D = “yes" or "no”
   xOffset = "number between -1 and 1"
   yOffset = "number between -1 and 1"
   rotated = "yes/no"
   showLegend = "yes/no"
   tipStyle = "MouseDown, MouseOver, Off"
   tipBGColor = "hex value or web color"
   showMarkers = ”yes" or "no”
   markerSize = "integer number of pixels"
   pieSliceStyle = "solid, sliced"
   url = “onClick destination page"
   name = "String"
   </cfchart>

See also

cfchartdata , cfchartseries

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute
Req/Opt
Default
Description
format
flash
File format in which to save graph.
  • flash
  • jpg
  • png
chartHeight
240
Chart height; integer number of pixels
chartWidth
320
Chart width; integer number of pixels
scaleFrom
Determined by data
Y-axis minimum value; integer.
scaleTo
Determined by data
Y-axis maximum value; integer
showXGridlines
no
  • yes: display X-axis gridlines
  • no: hide X-axis gridlines
showYGridlines
yes
  • yes: display Y-axis gridlines
  • no: hide Y-axis gridlines
gridlines
3 (top, bottom, and zero)
Number of grid lines to display on value axis, including axis; positive integer.
0: hide gridlines
seriesPlacement
default
Applies to charts that have more than one data series. Relative positions of series.
  • default: ColdFusion determines relative positions, based on graph types
  • cluster
  • stacked
  • percent
foregroundColor
black
Color of text, gridlines, and labels.
Hex value or supported named color; see name list in the Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
dataBackgroundColor
white
Color of area around chart data.
Hex value or supported named color; see name list in the Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
borderBackgroundColor
white
Color of area between data background and border, around labels and around legend.
Hex value or supported named color; see name list in the Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
showBorder
no
  • yes
  • no
font
arial
Name of text font
  • arial
  • times
  • courier
  • arialunicodeMS. This option is required, if you are using a double-byte character set on UNIX, or using a double-byte character set on Windows with a file type of Flash.
fontSize
11
Font size; integer
fontBold
no
  • yes
  • no
fontItalic
no
  • Yes
  • No
labelFormat
number
Format for Y-axis labels.
  • number
  • currency
  • percent
  • date
xAxisTitle
text; X-axis title
yAxisTitle
text; Y-axis title
sortXAxis
no
  • yes: display column labels in alphabetic order along X-axis
  • no
show3D
no
  • yes: display chart with three-dimensional appearance
  • no
xOffset
0.1
Applies if show3D="yes". Number of units by which to display the chart as angled, horizontally.
  • A number in the range -1 – 1, where "-1" specifies 90 degrees left and "1" specifies 90 degrees right
yOffset
0.1
Applies if show3D="yes". Number of units by which to display the chart as angled, vertically.
  • A number in the range -1 – 1, where "-1" specifies 90 degrees down, and "1" specifies 90 degrees up
rotated
no
  • yes: rotate chart 90 degrees. For a horizontal bar chart, use this option.
  • no
showLegend
yes
  • yes: if chart contains more than one data series, display legend
  • no
tipStyle
mouseOver
Determines the action that opens a popup window to display information about the current chart element.
  • mouseDown: displays if the user positions the cursor at the element and clicks the mouse down. Applies only to Flash format graph file. (For other formats, this option functions the same as mouseOver.)
  • mouseOver: displays if the user positions the cursor at the element
  • off: suppresses display
tipbgcolor
white
Applies only to Flash format graph file.
Hex value or supported named color; see name list in the Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
showMarkers
yes
Applies to chartseries type attribute values line, curve and scatter.
  • yes: display markers at data points
  • no
markerSize
(Automatic)
Size of data point marker. in pixels. Integer.
pieSliceStyle
sliced
Applies to chartseries type attribute value pie.
  • solid: displays pie as if unsliced
  • sliced: displays pie as if sliced
url
URL to open if the user clicks item in a data series; the onClick destination page.
You can specify variables within the URL string; ColdFusion passes current values of the variables.
  • $VALUE$: value of selected row. If none, value is empty string.
  • $ITEMLABEL$: label of selected item. If none, value is empty string.
  • $SERIESLABEL$: label of selected series. If none, value is empty string.
For example:
“somepage.cfm?item=$ITEMLABEL$&series=$SERIESLABEL$&value=$VALUE$”
  • "javascript:...": executes a client-side script
name
Page variable name. String. Outputs ISO-8859-1 encoded binary graph data and sets it as a variable in the page. Suppresses chart display. Used primarily by Flash Gateway users.

Usage

The cfchart tag defines a “container” in which a graph displays: its height, width, background color, labels, and so on. The cfchartseries tag defines the style in which data displays: bar, line, pie, and so on. The cfchartdata tag defines a data point.

Data is passed to the cfchartseries tag in the following ways:

  • As a query
  • As data points, using the cfchartdata tag

For the font attribute value "ArialUnicodeMS", the following rules apply:

  • On Windows: to permit Flash charts (type = "flash") to render double-byte character set, you must select this value
  • On UNIX: for all type values, to render a double-byte character set, you must select this value.
  • If this value is selected, the fontbold andfontitalic attributes have no effect

The color attributes accept the following W3C HTML 4 named color value or hex values:

Color name | RGB value
Black | #000000
Green | ##008000
Silver | ##C0C0C0
Lime | ##00FF00
Gray | ##808080
Olive | ##808000
White | ##FFFFFF
Yellow | ##FFFF00
Maroon | ##800000
Navy | ##000080
Red | ##FF0000
Blue | ##0000FF
Purple | ##800080
Teal | ##008080
Fuchsia | ##FF00FF
Aqua | ##00FFFF

For all other color values, you must enter the hex value.

For more color names that are supported by popular browsers, see:

http://www.w3.org/TR/css3-color

Flash does not conform fully to UNIX X11 naming conventions.

You can specify whether charts are cached in memory, the number of charts to cache, and the number of chart requests that ColdFusion can process concurrently. To set these options: in the ColdFusion Administrator, select Server Settings > Charting.


cfchartdata

Description

Used with the cfchart and cfchartseries tags. This tag defines chart data points. Its data is submitted to the cfchartseries tag.

Category

Data output tags, Extensibility tags

Syntax

<cfchartdata
   item = "text"
   value = "number">

See also

cfchart , cfchartseries

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
item |  |  | string; data point name
value |  |  | number or expression; data point value


cfchartseries

Description

Used with the cfchart tag. This tag defines the style in which chart data displays: bar, line, pie, and so on.

Category

Data output tags, Extensibility tags

Syntax

<cfchartseries
   type="type"
   query="queryName"
   itemColumn="queryColumn"
   valueColumn="queryColumn"
   seriesLabel="Label Text"
   seriesColor="Hex value or Web color"
   paintStyle="plain, raise, shade, light"
   markerStyle="style"
   colorlist = “list”>
</cfchartseries>

See also

cfchart , cfchartdata

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute
Req/Opt
Default
Description
type
Required
Sets the chart display style:
  • bar
  • line
  • pyramid
  • area
  • cone
  • curve
  • cylinder
  • step
  • scatter
  • pie
query
Optional
Name of ColdFusion query from which to get data.
itemColumn
Required if query attribute is specified
Name of a column in the query specified in the query attribute; contains the item label for a data point to graph.
valueColumn
Required if query attribute is specified
Name of a column in the query specified in the query attribute; contains data values to graph.
seriesLabel
Optional
Text of data series label
seriesColor
Optional
Color of the main element (such as the bars) of a chart. For a pie chart, the color of the first slice.
Hex value or supported named color; see name list in the cfchart Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
paintStyle
Optional
plain
Sets the paint display style of the data series.
  • plain: solid color
  • raise: the appearance of a button
  • shade: gradient fill, darker at the edges
  • light: a lighter shade of color; gradient fill
markerStyle
Optional
rectangle
Applies to chartseries type attribute values line, curve and scatter, and show3D attribute value no.
Sets the icon that marks a data point:
  • rectangle
  • triangle
  • diamond
  • circle
  • letter
  • mcross
  • snow
  • rcross
colorlist
Optional
Applies if chartseries type attribute = "pie". Sets pie slice colors.
Comma-delimited list of hex values or supported, named web colors; see name list in the cfchart Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.

Usage

For a pie chart, ColdFusion sets pie slice colors as follows:

  • If the seriesColor attribute is omitted, ColdFusion automatically colors the slices
  • If the seriesColor attribute is specified, ColdFusion automatically colors the slices after the first one, starting with the specified color for the first slice
  • If the colorList attribute is specified, ColdFusion colors the slices after the first one, according to the list


cfcol

Description

Defines table column header, width, alignment, and text. Used within a cftable tag.

Category

Data output tags

Syntax

<cfcol
   header = "column_header_text"
   width = "number_indicating_width_of_column"
   align = "Left" or "Right" or "Center"
   text = "column_text">

See also

cfcontent , cfoutput , cftable

History

New in ColdFusion MX: You can construct dynamic cfcol statements.

Attributes

Attribute
Req/Opt
Default
Description
header
Required
Column header text. To use this attribute, you must also use the cftable colHeaders attribute.
width
Optional
20
Column width. If the length of data displayed exceeds this value, data is truncated to fit. To avoid this, use an HTML table tag.
If the surrounding cftable tag includes the htmltable attribute, width specifies the percent of the table width and it does not truncate text; otherwise, width specifies the number of characters.
align
Optional
Left
Column alignment
  • Left
  • Right
  • Center
text
Required
Double-quotation mark-delimited text; determines what to display. Rules: same as for cfoutput sections. You can embed hyperlinks, image references, and input controls.

Usage

At least one cfcol tag is required within the cftable tag. You must put cfcol and cftable tags adjacent in a page. The only tag that you can nest within the cftable tag is the cfcol tag. You cannot nest cftable tags.

To display the cfcol header text, you must specify the cfcol header and the cftable colHeader attribute. If you specify either attribute without the other, the header does not display. No error is thrown.

Example

<!--- This example shows the use of cfcol and cftable to align
information returned from a query --->
<!--- query selects information from cfsnippets data source --->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
   SELECT Emp_ID, FirstName, LastName, EMail, Phone, Department
   FROM  Employees
</cfquery>
<html>
<body>
<h3>cfcol Example</h3>
<!--- Uses the HTMLTable attribute to display cftable as an HTML
table, rather than PRE formatted information --->
<cftable
   query = "GetEmployees"
   startRow = "1" colSpacing = "3"
   HTMLTable colheaders>
<!--- each cfcol tag sets the width of a column in the table,
the header information and the text/CFML for the cell --->
   <cfcol header = "<b>ID</b>"
      align = "Left"
      width = 2
      text  = "#Emp_ID#">
   <cfcol header = "<b>Name/Email</b>"
      align = "Left"
      width = 15
      text  = "<a href = ’mailto:#Email#’>#FirstName# #LastName#</A>">
   <cfcol header = "<b>Phone Number</b>"
      align = "Center"
      width = 15
      text  = "#Phone#">
</cftable>


cfcollection

Description

Creates, registers, and administers Verity search engine collections.

A collection that is created with the cfcollection tag is internal. A collection created any other way is external.

A collection that is registered with ColdFusion using the cfcollection tag or registered with the K2 Server by editing the k2server.ini file is registered. Other collections are unregistered.

An internal collection can be created in these ways:

  • With the cfcollection tag
  • In the ColdFusion Administrator, which calls the cfcollection tag

An external collection can be created using a native Verity indexing tool, such as Vspider or MKVDK.

Category

Extensibility tags

Syntax

<cfcollection
   action = "action"
   collection = "collection_name"
   path = "path_to_verity_collection"
   language = "language"
   name = "queryname" >

See also

cfexecute , cfindex , cfobject , cfreport , cfsearch , cfwddx

History

New in ColdFusion MX:

  • The action attribute is required.
  • The action attribute list value is new. It is the default.
  • It is not necessary to specify the action attribute value map. (ColdFusion detects collections and creates maps collections as required.)
  • This tag accepts collection names that include spaces.
  • ColdFusion supports Verity operations on Acrobat PDF files.
  • This tag can throw the SEARCHENGINE exception.

Attributes

Attribute
Req/Opt
Default
Description
action
Required; see Usage section
list
  • create: registers the collection with ColdFusion.
    • - If the collection is present: creates a map to it
    -If the collection is not present: creates it
  • repair: fixes data corruption in a collection.
  • delete: un-registers a collection.
    • - If the collection was registered with action = create: deletes its directories
    - If the collection was registered and mapped: does not delete collection directories
  • map: creates a map to the collection. It is not necessary to specify this value. (ColdFusion maps collections automatically.)
  • optimize: optimizes the structure and contents of the collection for searching; recovers space.
  • list: returns a query result set, named from the name attribute value, of the attributes of the collections that are registered by ColdFusion and K2 Server.
collection
Required
  • A collection name. The name can include spaces.
path
Optional
Absolute path to a Verity collection.
To map an existing collection, specify a fully-qualified path to the collection (not including the collection name). For example, "C:\MyCollections\"
language
Optional
English
Options are listed in Usage section. Requires the appropriate (European or Asian) Verity Locales language pack.
name
Required if action = "list"
Name for the query results returned by the list action.

Usage

With this tag you can create, register a Verity collection and administer a collection that was created by ColdFusion or by a Verity application.

The following table shows the dependence relationships among this tag’s attribute values:

Specifying this attribute is required, optional or unnecessary (blank): | For this action attribute value:
 | list | create | map | optimize | repair | delete
collection |  | Required | Required | Required | Required | Required
path |  | Optional | Optional |  |  |
language |  | Optional | Optional |  |  |
name | Required |  |  |  |  |

For all action values of this tag, use the cflock tag to protect the collection during tag execution.

To register a collection with K2Server, you update the k2server.ini file.

Before you attempt to delete or purge a collection that is also opened by the K2Server, you must stop the K2Server. If you do not, some files may be open, and ColdFusion might not complete the action.

The list action returns a result set that contains one row per collection:

Column
Contents
EXTERNAL
  • Yes: the collection is external
  • No: the collection is not external
  • Not Found: the collection is registered but is not available in the defined path
LANGUAGE
The locale setting of the collection.
This information is not available for K2Server collections.
MAPPED
  • Yes: the collection is mapped
  • No: the collection is not mapped
This information is not available for K2Server collections.
NAME
  • For a ColdFusion registered collection: its name
  • For a K2Server registered collection: its alias, defined in the k2server.ini file. (ColdFusion saves registered K2Server collection information; it is available regardless of whether the K2Server is running)
ONLINE
  • Yes: the collection can be searched
  • No: the collection cannot be searched
If EXTERNAL = "Not Found", this value is "No".
PATH
Absolute path to the collection. If the collection is mapped or is registered by a K2Server, the path includes the collection name.
REGISTERED
  • CF: collection is registered by ColdFusion
  • K2: collection is registered by K2Server

You can also display this information in the Administrator, under Verity > Collections.

If the K2 Server is not running when the list action is executed, the result set returned contains K2Server information that was current when the server became unavailable.

To determine whether a collection exists, use code such as the following, to execute a query of queries:

<cflock name="verity" timeout="60">
   <cfcollection action="list" name="myCollections" >
</cflock>
<cfquery name="qoq" dbtype="query">
select * from myCollections
where myCollections.name = 'myCollectionName'
</cfquery>
<cfdump var = #qoq#>

To get a result set with values for all the collections that are registered with the ColdFusion and K2 servers, use code such as the following:

<cflock name="verity" timeout="60">
   <cfcollection action="list" name="myCollections">
</cflock>
<cfoutput query="myCollections">
   #name#<br>
</cfoutput>

To add content to a collection, use cfindex. To search a collection, use cfsearch .

With the European Verity Locales language pack installed, the language attribute of this tag supports the following options:

bokmal | french | norweg
danish | german | portug
dutch | italian | portuguese
english | nynorsk | spanish
finnish | norwegian | swedish

With the Asian Verity Locales language pack installed, the language attribute of this tag supports the following options:

arabic | hungarian | russian
czech | japanese | simplified_chinese
greek | korean | traditional_chinese
hebrew | polish | turkish

The default location of Verity collections is as follows:

  • Windows: C:\CFusionMX\verity\collections
  • Unix system: /opt/coldfusionmx/verity/collections

Example

<!--- for ACTION=UPDATE ----------------------------------------------->
<!--- for ACTION=UPDATE, #1 (TYPE=FILE) (key is a filename) ---->
<cfindex
      collection="snippets"
      action="update"
      type="file"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2" >

<!--- for ACTION=UPDATE, #2 (TYPE=FILE) (key is a query result set column) ---->
<cfquery       name="bookquery"
      datasource="book">
      select *from book where bookid='file'
</cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="update"
      type="file"
      query="bookquery"
      key="description"
      urlpath="url">

<!--- for ACTION=UPDATE, #3 (TYPE=PATH) (extensions .htm, .html,.cfm,.cfml) --->
<cfindex       collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions=".htm, .html, .cfm, .cfml" >

<!--- for ACTION=UPDATE, #4 (TYPE=PATH)
      (extensions are       files with no extension) ---->
<cfindex
      collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions="*." >

<!--- for ACTION=UPDATE, #5 (TYPE=PATH)
      (extensions are files with any extension) ---->
<cfindex
      collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions=".*">

<!--- for ACTION=UPDATE, #6 (TYPE=PATH) (where the key
      is a query result set column) ---->
<cfquery       name="bookquery"
      datasource="book">
      select * from book where bookid='path1' or bookid='path2'
</cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="update"
      type="path"
      query="bookquery"
      key="description"
      urlpath="url" >

<!--- for ACTION=UPDATE, #7 (TYPE=CUSTOM) ---->
<cfquery       name="book"
      datasource="book">
      select * from book
</cfquery>
<cfindex
      collection="custom_book"
      action="update"
      type="custom"
      body="description"
      key="bookid"
      query="book">

<!--- for ACTION=REFRESH----------------------------------------------->
<!--- ACTION=REFRESH, #1 (TYPE=FILE) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="Refresh"
      type="file"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm"
      urlpath="http://localhost/"
      custom1="custom1"
      custom2="custom2" >
</cflock>

<!--- ACTION=REFRESH, #2 (TYPE=PATH) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="refresh"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets/"
      custom1="custom1"
      custom2="custom2"
      recurse="yes"
      extensions=".htm,.html,.cfm,.cfml" >
</cflock>

<!--- ACTION=REFRESH, #3 (TYPE=CUSTOM) ---->
<cfquery       name="book"
      datasource="book">
      select * from book
</cfquery>
<cfindex
      collection="custom_book"
      action="refresh"
      type="custom"
      body="description"
      key="bookid"
      query="book">

<!--- for ACTION=DELETE----------------------------------------------->

<!--- ACTION=DELETE, #1 (TYPE=FILE) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="delete"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm" >
</cflock>

<!--- ACTION=DELETE, #2 (TYPE=FILE) (the key is a query result set column) ---->
<cflock       name="verity"
      timeout="60">
<cfquery       name="book"
      datasource="book">
      select * from book where bookid='file'
</cfquery>
<cfoutput
      query="book">
          --#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="delete"
      type="file"
      query="book"
      key="description" >
</cflock>

<!--- ACTION=DELETE, #3 (TYPE=PATH) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="delete"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      extensions=".cfm"
      recurse="no">
</cflock>

<!--- ACTION=DELETE, #4 (TYPE=PATH) (key is a query result set column) ---->
<cflock       name="verity"
      timeout="60">
<cfquery
      name="bookquery"
      datasource="book">
          select * from book where bookid='path1'
        </cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="delete"
      type="path"
      query="bookquery"
      key="description" >
</cflock>

<!--- ACTION=DELETE, #5 (TYPE=CUSTOM) ---->
<cflock name="verity"
      timeout="60">
<cfquery       name="book"
      datasource="book">
      select * from book where bookid='bookid1'
</cfquery>
<cfindex
      collection="custom_book"
      action="delete"
      type="custom"
      query="book"
      key="bookid" >
</cflock>

<!--- for ACTION=PURGE----------------------------------------------->
<cflock name="verity"
      timeout="60">
<cfindex
      action="purge"
      collection="snippets">
</cflock>


cfcomponent

Description

Creates and defines a component object; encloses functionality that you build in CFML and enclose within cffunction tags. This tag contains one or more cffunction tags that define methods. Code within the body of this tag, other than cffunction tags, is executed when the component is instantiated.

A component file has the extension CFC and is stored in any directory of an application.

A component is invoked in the following ways:

  • Within the cfinvoke tag in a ColdFusion page
  • Within a URL that calls a CFC file and passes a method name as a URL parameter
  • Within the cfscript tag
  • As a web service
  • From Flash code

Category

Extensibility tags

Syntax

<cfcomponent
   extends ="anotherComponent"
   output = "yes" or "no">
   <cffunction ...>
      ...
   </cffunction>

   <cffunction ...>
      ...
   </cffunction>
</cfcomponent>

See also

cfargument , cffunction , cfinvoke , cfinvokeargument , cfobject , cfproperty , cfreturn

Attributes

Attribute
Req/Opt
Default
Description
extends
Optional
Name of parent component from which to inherit methods and properties.
output
Optional
  • yes: permits component method output
  • no: suppresses component method output

Usage

ColdFusion processes output expressions as follows:

  • If "output=no", ColdFusion suppresses all output.
  • If "output=yes", ColdFusion evaluates all #expr# tokens as if the function body was enclosed within cfoutput tags.
  • If you do not specify the output attribute, you must enclose all tokens that are to be evaluated within cfoutput tags.

This tag requires an end tag.

Example

<cfcomponent>
   <cffunction name="getEmp">
       <cfquery
name="empQuery" datasource="ExampleApps" >
          SELECT FIRSTNAME, LASTNAME, EMAIL
          FROM tblEmployees
       </cfquery>
       <cfreturn empQuery>
   </cffunction>

   <cffunction name="getDept">
      <cfquery
name="deptQuery" datasource="ExampleApps" >
          SELECT *
          FROM tblDepartments
       </cfquery>
       <cfreturn deptQuery>
   </cffunction>
</cfcomponent>


cfcontent

Description

Downloads a file from the server to the client. Sets the file or MIME content encoding of content returned by the current page. Sets the name of a file that is downloaded by the current page.

Note: For this tag execute, it must be enabled in the ColdFusion Administrator. For more information, see Administering ColdFusion MX.

Category

Data output tags

Syntax

<cfcontent
   type = "file_type"
   deleteFile = "Yes" or "No"
   file = "filename"
   reset = "Yes" or "No">

See also

cfcol , cfoutput , cftable

Attributes

Attribute
Req/Opt
Default
Description
type
Optional. You must specify one of these: type, file, reset
A file or MIME content type, optionally including character encoding, in which to return the page.
  • text/html
  • (any valid type)
The following character set values are typically used:
  • charset=UTF-8
  • charset=ISO-8859-1
  • charset=UTF-16
  • charset=US-ASCII
  • charset=UTF-16BE
  • charset=UTF-16LE
For example:
type = "text/html"
type = "text/html; charset = ISO-8859-1"
The semi-colon is optional.
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html
deleteFile
Optional
No
Applies only if you specify a file with the file attribute.
  • Yes: deletes a file after the download operation
  • No
file
Optional
Name of file to get. When using ColdFusion in a distributed configuration, the file attribute must refer to a path on the system on which the web server runs.
reset
Optional
Yes
The reset and file attributes are mutually exclusive. If you specify a file, this attribute has no effect. See Note.
  • Yes: discards output that precedes call to cfcontent
  • No: preserves output that precedes call to cfcontent

Note: If you call this tag from a custom tag, and you do not want the tag to discard the current page when it is called from another application or custom tag, set reset = "no".

Usage

To set the character encoding of generated output, use code such as the following:

<cfcontent type="text/html; charset=ISO-8859-1">

If a file delete operation is unsuccessful, ColdFusion throws an error.

When ColdFusion processes an HTTP request, it determines the character set of the data returned in the HTTP response. By default, ColdFusion returns character data using the Unicode UTF-8 format (regardless of the value of an HTML meta tag in the page). Within a ColdFusion page, you can override the default character encoding of the response, using the cfcontent tag. To specify the MIME type and character set of the page output, use the type attribute, as follows:

<cfcontent type="text/html charset=EUC-JP">

The following example shows how you might display the results of a query, in an Excel spreadsheet within a ColdFusion page.

<!--- use cfsetting to block output of HTML that is not within cfoutput tags --->
<cfsetting enablecfoutputonly="Yes">

<!--- get Employee info --->
<cfquery name="GetEmps" datasource="CompanyInfo">
   SELECT * FROM Employee
</cfquery>

<!--- Set variables for special chars --->
<cfset TabChar = Chr(9)>
<cfset NewLine = Chr(13) & Chr(10)>

<!--- Set content type to invoke Excel --->
<cfcontent type="application/msexcel">

<!--- suggest default name for XLS file --->
<!--- use "Content-Disposition" in cfheader for Internet Explorer  --->
<cfheader name="Content-Disposition" value="filename=Employees.xls">

 <!--- output data, each row on one line--->
<cfloop query="GetEmps">
   <cfoutput>#Emp_ID##TabChar##LastName#
   #TabChar##FirstName##TabChar##Salary##NewLine#</cfoutput>
</cfloop>

If you use this tag after the cfflush tag on a page, ColdFusion throws an error.

Example

<!--- This example shows the use of cfcontent to return the contents of the CF
Documentation page dynamically to the browser. You might need to change
the path and/or drive letter. (graphics do not display) --->
<!--- Files may be set to delete after downloading, allowing
for posting of changing content. --->
<cfcontent type = "text/html"
file = "c:\inetpub\wwwroot\cfdocs\main.htm"
deleteFile = "No">
<!--- This example shows how reset attribute changes text output. --->
<html>
<body>
<h3>cfcontent Example 2</h3>

<p>This example shows how reset attribute changes output for text.</p>
<p>reset = "Yes ": 123
<cfcontent type = "text/html" reset = "Yes ">456</p>
<p>This example shows how reset attribute changes output for text.</p>
<p>reset = "No ": 123
<cfcontent type = "text/html" reset = "No ">456</p>


cfcookie

Description

Defines web browser cookie variables, including expiration and security options.

Category

Forms tags, Variable manipulation tags

Syntax

<cfcookie
   name = "cookie_name"
   value = "text"
   expires = "period"
   secure = "Yes" or "No"
   path = "url"
   domain = ".domain">

See also

cfdump , cfparam , cfregistry , cfsavecontent , cfschedule , cfset

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of cookie variable.
value
Optional
Value to assign to cookie variable.
expires
Optional
now
Expiration of cookie variable.
  • A date (for example, 10/09/97)
  • A number of days (for example, 10, or 100)
  • now: deletes cookie from client cookie.txt file
  • never: never deletes cookie from client; writes cookie data to cookie.txt file
secure
Optional
If browser does not support Secure Sockets Layer (SSL) security, cookie is not sent.
  • Yes: variable must be transmitted securely
  • No
path
Optional
URL, within a domain to which the cookie applies.
path = "/services/login"
To specify multiple URLs, use multiple cfcookie tags.
If you specify path, you must also specify domain.
domain
Required if path attribute is specified
Domain in which cookie is valid and to which cookie content can be sent. Must start with a period. If the value is a subdomain, the valid domain is: all domain names that end with this string. The cookie is set securely only if the page in which the cookie is used is referenced using the https:// protocol.
For a domain value that ends in a country code, the specification must contain at least three periods; for example, "mongo.state.us". For special top-level domains, two periods are required; for example, ".mgm.com".
You cannot use an IP address as a domain.

Usage

If this tag specifies that a cookie is to be saved beyond the current browser session, ColdFusion writes or updates the cookie to the cookies.txt file. Until the browser is closed, the cookie resides in memory. If the expires attribute is not specified, the cookie is written to the cookies.txt file.

If you use this tag after the cfflush tag on a page, ColdFusion throws an error.

To set cookies and execute a redirect in the same page, use the cfheader tag to specify the new target URL; for example:

<cfheader name="location" value="OtherPage.cfm?foo=bar">
<cfheader statusCode="302" statusText="Document Moved">
<cfabort>

You can use dots in names within the cookie and client variable scopes, as the following examples show:

<cfcookie name="person.name" value="wilson, john">
<cfset cookie.person.lastname="Santiago">
<cfcookie name="a.b.c" value="a value">
<cfset client.foo.bar="a_value">

Caution:Do not set a cookie variable on the same page on which you use the cflocation tag. If you do, the cookie is never saved on the browser.

Example

<!--- This example shows how to set/delete a cfcookie variable --->
<!--- Select users who have entered comments into sample database --->
<cfquery name = "GetAolUser" dataSource = "cfsnippets">
   SELECT EMail, FromUser, Subject, Posted
   FROM  Comments
</cfquery>
<html>
<body>
<h3>cfcookie Example</h3>
<!--- if the URL variable delcookie exists, set cookie expiration date to NOW --->
<cfif IsDefined("url.delcookie") is True>
   <cfcookie name = "TimeVisited"
   value = "#Now()#"
   expires = "NOW">
<cfelse>
<!--- Otherwise, loop through list of visitors; stop when you match
the string aol.com in a visitor’s e-mail address --->
<cfloop query = "GetAolUser">
   <cfif FindNoCase("aol.com", Email, 1) is not 0>
      <cfcookie name = "LastAOLVisitor"
      value = "#Email#"
      expires = "NOW" >
   </cfif>
</cfloop>
<!--- If the timeVisited cookie is not set, set a value --->
   <cfif IsDefined("Cookie.TimeVisited") is False>
      <cfcookie name = "TimeVisited"
      value = "#Now()#"
      expires = "10">
   </cfif>
</cfif>
<!--- show the most recent cookie set --->
<cfif IsDefined("Cookie.LastAOLVisitor") is "True">
   <p>The last AOL visitor to view this site was
   <cfoutput>#Cookie.LastAOLVisitor#</cfoutput>, on
   <cfoutput>#DateFormat(COOKIE.TimeVisited)#</cfoutput>
<!--- use this link to reset the cookies --->
<p><a href = "cfcookie.cfm?delcookie = yes">Hide my tracks</A>
<cfelse>
   <p>No AOL Visitors have viewed the site lately.
</cfif>


cfdefaultcase

Description

Used with the cfswitch and cfcase tags.

For more information, see cfswitch.

Category

Flow-control tags


cfdirectory

Description

Manages interactions with directories.

Category

File management tags

Note: For this tag execute, it must be enabled in the ColdFusion Administrator. For more information, see Administering ColdFusion MX.

If you put ColdFusion applications on a server that is used by multiple customers, you must consider the security of files and directories that could be uploaded or otherwise manipulated with this tag by unauthorized users. For more information about securing ColdFusion tags, see Administering ColdFusion MX.

Syntax

<cfdirectory
   action = "directory action"
   directory = "directory name"
   name = "query name"
   filter = "list filter"
   mode = "permission"
   sort = "sort specification"
   newDirectory = "new directory name">

See also

cffile

History

New in ColdFusion MX: On Windows, if cfdirectory action = "list", this tag does not return the directory entries "." (dot) or ".." (dot dot), which represent "the current directory" and "the parent directory." (In earlier releases, ColdFusion returned these entries.)

New in ColdFusion MX:

  • Code such as the following, which was acceptable in earlier releases, may cause incorrect output in ColdFusion MX:
    • <cfdirectory action = "list" directory ="c:\" name="foo>
Files in c:\<br>
<cfloop query = "foo" startrow = 3>
   #name#<br>
>
  • Code such as the following, which was acceptable in earlier releases, is acceptable in ColdFusion MX, although it is unnecessary:
    • <cfdirectory directory="c:\" name="foo">
Files in c:\<br>
<cfoutput query="foo">
   <cfif NOT foo.name is "." AND NOT foo.name is "..">
      #name#<br>
   </cfif>
</cfoutput>

Attributes

Attribute
Req/Opt
Default
Description
action
Optional
List
  • list: returns a query record set of the files in the specified directory. The directory entries "." (dot) and ".." (dot dot), which represent the current directory and the parent directory, are not returned.
  • create
  • delete
  • rename
directory
Required
Absolute pathname of directory against which to perform action.
name
Required if action = "list"
Name for output record set.
filter
Optional if action = "list"
File extension filter applied to returned names. For example: *.cfm. One filter can be applied.
mode
Optional
Used with action = "create". Permissions. Applies only to Solaris and HP-UX. Octal values of chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
sort
Optional; used if action = "list"
ASC
Query column(s) by which to sort directory listing. Delimited list of columns from query output.
To qualify a column, use:
  • ac: ascending (a to z) sort order
  • desc: descending (z to a) sort order
For example:
sort = "dirname ASC, file2 DESC, size, datelastmodified"
newDirectory
Required if action = "rename"
New name for directory

Usage

If action = "list", cfdirectory returns these result columns, which you can reference in a cfoutput tag:

  • name: directory entry name. The entries "." and ".." are not returned.
  • size: directory entry size
  • type: file type: File, for a file; Dir, for a directory
  • dateLastModified: the date that an entry was last modified
  • attributes: file attributes, if applicable
  • mode: (UNIX and Linux only) see the UNIX man pages, chmod shell command.

You can use the following result columns in standard CFML expressions, preceding the result column name with the query name:

#mydirectory.name#
#mydirectory.size#
#mydirectory.type#
#mydirectory.dateLastModified#
#mydirectory.attributes#
#mydirectory.mode#

Example

<h3>cfdirectory Example</h3>
<!--- use cfdirectory to give the contents of the snippets directory,
order by name and size (you may need to modify this path) --->
<cfdirectory
   directory="#GetDirectoryFromPath(GetTemplatePath())#"
   name="myDirectory"
   sort="name ASC, size DESC">
<!---- Output the contents of the cfdirectory as a cftable ----->
<cftable
   query="myDirectory"
   htmltable
   colheaders>
   <cfcol
      header="NAME:"
      text="#Name#">
   <cfcol
      header="SIZE:"
      text="#Size#">
</cftable>


cfdump

Description

Outputs the elements, variables and values of most kinds of ColdFusion objects. Useful for debugging. You can display the contents of simple and complex variables, objects, components, user-defined functions, and other elements.

Category

Debugging tags, Variable manipulation tags

Syntax

<cfdump
   var = #variable#
   expand = "Yes or No"
   label = "text">

See also

cfcookie, cfparam, cfsavecontent, cfschedule, cfset, cfwddx

Attributes

Attribute
Req/Opt
Default
Description
var
Required
Variable to display. Enclose a variable name in pound signs.
These kinds of variables yield meaningful cfdump displays:
  • array
  • CFC
  • Java object
  • simple
  • query
  • structure
  • UDF
  • wddx
  • xml
expand
Optional
Yes
  • Yes: In Internet Explorer and Mozilla, expands views
  • No: contracts expanded views
label
Optional
A string; header for the dump output.

Usage

The expand/contract display capability is useful when working with large structures, such as XML document objects, structures, and arrays.

To display a construct, use code such as the following, in which myDoc is a variable of type XmlDocument:

<cfif IsXmlDoc(mydoc) is "True">
   <cfdump var=#mydoc#>
</cfif>

The tag output is color-coded according to data type.

If a table cell is empty, this tag displays "[empty string]".

Example

This example shows how to use this tag to display a URL variable. URL variables contain parameters that are passed in a URL string in a page request.

<cfdump var="#URL#">


cfelse

Description

Used with the cfif and cfelseif tags.

For more information, see cfif.

Category

Flow-control tags


cfelseif

Description

Used with the cfif and cfelse tags.

For more information, see cfif.

Category

Flow-control tags


cferror

Description

Displays a custom HTML page when an error occurs. This lets you maintain a consistent look and feel among an application’s functional and error pages.

Category

Exception handling tags, Extensibility tags, Application framework tags

Syntax

<cferror
   type = "a type"
   template = "template_path"
   mailTo = "email_address"
   exception = "exception_type">

See also

cfrethrow , cfthrow , cftry

History

New in ColdFusion MX: the monitor option of the exception attribute is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/Opt
Default
Description
type
Required
Type of error that the custom error page handles:
  • application: application exceptions
  • database: database exceptions
  • template: ColdFusion page exceptions
  • security: security exceptions
  • object: object exceptions
  • missinginclude: missing include file exceptions
  • expression: expression exceptions
  • lock: lock exceptions
  • custom_type: developer-defined exceptions, defined in the cfthrow tag
  • any: all exception types
template
Required
Relative path to the custom error page. (A ColdFusion page was formerly called a template.)
mailTo
Optional
E-mail address. Value for the error page variable error.mailto. Available to a custom error page; for example: #error.mailTo#.
exception
Type of exception that the tag generates:
  • an exception of the cftry tag; see cftry
  • a custom exception, coded in a cfthrow tag

Usage

Use this tag to provide custom error messages for pages in an application. You generally embed this tag in the Application.cfm file. For more information, see Administering ColdFusion MX.

In exception error handling pages, you can access the error variables of the cfcatch tag; see cftry. To do this, prefix these variables with "cferror."

To ensure that error pages display successfully, avoid using the cfencode tag to encode pages that include the cferror tag.


Templates (pages)

The following table describes the page to use for each type of error. (A ColdFusion page was formerly commonly called a template.)

Page type | Description | Use
Exception or Error | Dynamically invoked by the CFML language processor when it detects an unhandled exception condition. You can specify exception-handling pages in an application, using cferror type = "exception". In the ColdFusion Administrator, you can set a site-wide error handler, to handle exceptions that are not handled by an exception-handling page. | Uses the full range of CFML tags
Request | Includes the error variables described in the Error Variables section. | As a backup error handler for sites with high user interface requirements.
Validation | Handles data input validation errors that occur when submitting a form. Handles only hidden form-field style validation errors. You can specify the validation page in a cferror tag, directly on the action page. | You must include the validation error handler in the Application.cfm file.


Error variables

The exception-handling page specified in the cferror tag template attribute, contains one or more error variables. ColdFusion substitutes the value of the error variable when an error displays.

The following table lists error variables:

Page type | Error variable | Description
Exception | error.diagnostics | Detailed error diagnostics from ColdFusion Server
 | error.mailTo | E-mail address (same as value in cferror.MailTo)
 | error.dateTime | Date and time when error occurred
 | error.browser | Browser that was running when the error occurred
 | error.generatedContent | Failed request’s generated content
 | error.remoteAddress | IP address of remote client
 | error.HTTPReferer | Page from which client accessed link to page where error occurred
 | error.template | Page executing when error occurred
 | error.queryString | URL query string of client's request
Validation | error.validationHeader | Validation message header text
 | error.invalidFields | Unordered list of validation errors
 | error.validationFooter | Validation message footer text
Request and Exception | error.diagnostics | Detailed error diagnostics from ColdFusion Server
 | error.mailTo | E-mail address (same as value in cferror.MailTo)
 | error.dateTime | Date and time when error occurred
 | error.browser | Browser that was running when error occurred
 | error.remoteAddress | IP address of remote client
 | error.HTTPReferer | Page from which client accessed link to page where error occurred
 | error.template | Page executing when error occurred
 | error.queryString | URL query string of client's request
Exception only | error.messge | Error message associated with the exception.
 | error.rootCause | Java servelet exception reported by the JVM as the cause of the "root cause" of the exception. This variable is a Java object.
 | error.tagContext | Array of structures structure containing information for each tag in the tag stack The tag stack consists of each tag that is currently open.
 | error.type | Exception type.

Note: If type = "exception" or "monitor", you can substitute the prefix cferror for Error; for example, cferror.diagnostics, cferror.mailTo, or cferror.dateTime.

Example

<h3>cferror Example</h3>
<p>cferror lets you display custom HTML pages when errors occur. This lets you
maintain a consistent look and feel within the application even when
errors occur. No CFML can be displayed in the pages, except specialized
error variables.
<p>cftry/cfcatch is a more interactive way to handle CF errors within a CF page
than cferror, but cferror is a good safeguard against general errors.
<p>You can also use cferror within Application.cfm to specify error
handling responsibilities for an entire application.
<!--- Example of cferror call within a page --->
<cferror type = "REQUEST"
    template = "request_err.cfm"
    mailTo = "admin@mywebsite.com">
<!--- Example of the page to handle this error --->
<!---
<html>
<head>
   <title>We’re sorry -- An Error Occurred</title>
</head>
<body>
<ul>
<cfoutput>
   <li><b>Your Location:</b> #error.remoteAddress#
   <li><b>Your Browser:</b> #error.browser#
   <li><b>Date and Time the Error Occurred:</b> #error.dateTime#
   <li><b>Page You Came From:</b> #error.HTTPReferer#
   <li><b>Message Content</b>: <br><HR width = 50%>
    <p>#error.diagnostics#<HR width = 50%><p>
   <li><b>Please send questions to:</b>
    <a href = "mailto:#error.mailTo#">#error.mailTo#</A>
</cfoutput>
</ul>


cfexecute

Description

Executes a ColdFusion developer-specified process on a server computer.

Category

Extensibility tags, Flow-control tags

Syntax

<cfexecute
   name = " ApplicationName "
   arguments = "CommandLine Arguments"
   outputFile = "Output file name"
   timeout = "Timeout interval">
   ...
</cfexecute>

See also

cfcollection , cfindex , cfobject , cfreport , cfsearch , cfwddx

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Absolute path of the application to execute.
On Windows, you must specify an extension; for example, C:\myapp.exe.
arguments
Optional
Command-line variables passed to application. If specified as string, it is processed as follows:
  • Windows: passed to process control subsystem for parsing.
  • UNIX: tokenized into an array of arguments. The default token separator is a space; you can delimit arguments that have embedded spaces with double quotation marks.
If passed as array, it is processed as follows:
  • Windows: elements are concatenated into a string of tokens, separated by spaces. Passed to process control subsystem for parsing.
  • UNIX: elements are copied into an array of exec() arguments.
outputFile
Optional
File to which to direct program output. If not specified, output is displayed on page from which it was called.
timeout
Optional
0
Length of time, in seconds, that ColdFusion waits for output from the spawned program.
  • 0: equivalent to non-blocking mode.
  • A very high value: equivalent to blocking mode
If the value is 0:
  • ColdFusion starts a process and returns immediately. ColdFusion may return control to the calling page before any program output displays. To ensure that program output displays, set the value to 2 or higher.
  • If the outputFile attribute is not specified, any program output is discarded

Usage

Do not put other ColdFusion tags or functions between the start and end tags of cfexecute. You cannot nest cfexecute tags.

Exception

Throws the following exceptions:

  • If the application name is not found: Application File Not Found
  • If the output file cannot be opened: Output File Cannot
  • If the effective user of the ColdFusion executing thread does not have permissions to execute the process: a security exception

The time out values must be between zero and the longest time out value supported by the operating system.

Example

<h3>cfexecute</h3>
<p>This example executes the Windows NT version of the netstat network
monitoring program, and places its output in a file.

<cfexecute name = "C:\WinNT\System32\netstat.exe"
   arguments = "-e"
   outputFile = "C:\Temp\output.txt"
   timeout = "1">
</cfexecute>


cfexit

Description

This tag aborts processing of the currently executing CFML custom tag, exits the page within the currently executing CFML custom tag, or re-executes a section of code within the currently executing CFML custom tag.

Category

Debugging tags, Flow-control tags

Syntax

<cfexit
   method = "method">

See also

cfabort , cfbreak , cfexecute , cfif , cflocation , cfloop , cfswitch , cfthrow , cftry

Attributes

Attribute
Req/Opt
Default
Description
method
Optional
exitTag
  • exittag: aborts processing of currently executing tag
  • exittemplate: exits page of currently executing tag
  • loop: reexecutes body of currently executing tag

Usage

If this tag is encountered outside the context of a custom tag, for example in the base page or an included page, it executes in the same way as cfabort. The cfexit tag can help simplify error checking and validation logic in custom tags.

The cfexit tag function depends on its location and execution mode:

Method value | Location of cfexit call | Behavior
exitTag | Base page | Terminate processing
 | Execution mode = Start | Continue after end tag
 | Execution mode = End | Continue after end tag
exitTemplate | Base page | Terminate processing
 | Execution mode = Start | Continue from first child in body
 | Execution mode = End | Continue after end tag
loop | Base page | Error
 | Execution mode = Start | Error
 | Execution mode = End | Continue from first child in body

Example

<h3>cfexit Example</h3>
<p>cfexit can be used to abort the processing of the currently executing
CFML custom tag. Execution resumes following the invocation of
the custom tag in the page that called the tag.
<h3>Usage of cfexit</h3>
<p>cfexit is used primarily to perform a conditional stop of processing
inside a custom tag. cfexit returns control to the page that
called that custom tag, or in the case of a tag called by another
tag, to the calling tag.

<!--- cfexit can be used within a CFML custom tag, as follows: --->
<!--- Place this code (uncomment the appropriate sections) within the
CFUSION/customtags directory --->

<!--- MyCustomTag.cfm --->
<!--- This simple custom tag checks for the existence
of myValue1 and myValue2. If they are both defined,
the tag adds them and returns the result to the calling
page in the variable "result". If either or both of the
expected attribute variables is not present, an error message
is generated, and cfexit returns control to the
calling page. --->

<!--- <cfif NOT IsDefined("attributes.myValue2")>
         <cfset caller.result = "Value2 is not defined">
         <cfexit method = "exitTag">
    <cfelseif NOT IsDefined("attributes.myValue1")>
         <cfset caller.result = "Value1 is not defined">
         <cfexit method = "exitTag">
    <cfelse>
          <cfset value1 = attributes.myValue1>
          <cfset value2 = attributes.myValue2>
         <cfset caller.result = value1 + value2>
    </cfif> --->
<!--- End MyCustomTag.cfm --->

<!--- Place this code within your page --->

<!--- <p>The call to the custom tag, and then the result:
<CF_myCustomTag
      myvalue2 = 4>
<cfoutput>#result#</cfoutput> --->
<p>If cfexit is used outside a custom tag, it functions like a cfabort.
For example, the text after this message is not processed:
<cfexit>
<p>This text is not executed because of the cfexit tag above it.


cffile

Description

Manages interactions with files on the ColdFusion server.

The following sections describe the actions of the cffile tag:

  • cffile action = "upload"
  • cffile action = "move"
  • cffile action = "rename"
  • cffile action = "copy"
  • cffile action = "delete"
  • cffile action = "read"
  • cffile action = "readBinary"
  • cffile action = "write"
  • cffile action = "append"

Note: To execute, this tag must be enabled in the ColdFusion Administrator. For more information, see Administering ColdFusion MX.

If your ColdFusion applications run on a server used by multiple customers, consider the security of the files that could be uploaded or manipulated by cffile. For more information, see Administering ColdFusion MX.

Category

File management tags

Syntax

The tag syntax depends on the action attribute value. See the following sections.

See also

cfdirectory

History

New in ColdFusion MX: ColdFusion does not require that you put files and directories that you manipulate with this tag below the root of the web server document directory.

New in ColdFusion MX: A directory path that you specify in the destination attribute does not require a trailing slash.

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system values of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

New in ColdFusion MX: The action attribute options read, write, append and move support a new attribute, charset.

Example

<!--- This shows how to write, read, update, and delete a file using CFFILE --->
This is a view-only example.
<!---
<cfif IsDefined("form.formsubmit") is "Yes">
   <!--- form has been submitted, now do the action --->
   <cfif form.action is "new">
      <!--- make a new file --->
      <cffile          action="Write"
         file="#GetTempDirectory()#foobar.txt"
         output="#form.the_text#">
   </cfif>
   <cfif form.action is "read">
      <!--- read existing file --->
      <cffile          action="Read"
            file="#GetTempDirectory()#foobar.txt"
            variable="readText">
   </cfif>

   <cfif form.action is "add">
      <!--- update existing file --->
      <cffile          action="Append"
         file="#GetTempDirectory()#foobar.txt"
         output="#form.the_text#">
   </cfif>

   <cfif form.action is "delete">
      <!--- delete existing file --->
      <cffile       action="Delete"
         file="#GetTempDirectory()#foobar.txt">
   </cfif>
</cfif>
<!--- set some variables --->
<cfparam    name="fileExists"    default="no">
<cfparam name="readText" default="">
<!--- first, check if canned file exists --->
<cfif FileExists("#GetTempDirectory()#foobar.txt") is "Yes">
   <cfset fileExists="yes">
</cfif>
<!--- now, make the form that runs the example --->
<form action="index.cfm" method="POST">
<h4>Type in some text to include in your file:</h4> <p>
<cfif fileExists is "yes">
   A file exists (foobar.txt, in <cfoutput>#GetTempDirectory()#</cfoutput>).
   You may add to it, read from it, or delete it.
</cfif> <
!--- if reading from a form, let that information display in textarea --->
<textarea name="the_text" cols="40" rows="5">
   <cfif readText is not "">
      <cfoutput>#readText#</cfoutput>
   </cfif></textarea>
<!--- select from the actions depending on whether the file exists --->
<select name="action">
<cfif fileExists is "no">
   <option value="new">Make new file
</cfif>
<cfif fileExists is "yes">
   <option value="add">Add to existing file
   <option value="delete">Delete file
   <option value="read">Read existing file
</cfif>
</select>
<input type="Hidden" name="formsubmit" value="yes">
<input type="Submit" name="" value="make my changes">
</form> --->


cffile action = "upload"

Description

Copies a file to a directory on the server.

Syntax

<cffile
   action = "upload"
   fileField = "formfield"
   destination = "full_path_name"
   nameConflict = "behavior"
   accept = "mime_type/file_type"
   mode = "permission"
   attributes = "file_attribute_or_list">

See also

cfdirectory

History

New in ColdFusion MX: A directory path that you specify in the destination attribute does not require a trailing slash.

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system options of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
fileField
Required
Name of form field used to select the file.
Do not use pound signs (#) to specify the field name.
destination
Required
Absolute pathname of directory or file on web server.
ColdFusion 5 and earlier: trailing slash in directory path is required. ColdFusion MX: trailing slash in directory path is optional. On Windows, use backward slashes; on UNIX, use forward slashes.
nameConflict
Optional
Error
Action to take if filename is the same as that of a file in the directory.
  • Error: file is not saved. ColdFusion stops processing the page and returns an error.
  • Skip: file is not saved. This option permits custom behavior based on file properties.
  • Overwrite: replaces file.
  • MakeUnique: forms a unique filename for the upload; name is stored in the file object variable serverFile.
accept
Optional
Limits the MIME types to accept. Comma-delimited list. For example, to permit JPG and Microsoft Word file uploads:
accept = "image/jpg, application/msword"
The browser uses file extension to determine file type.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal (if you use this option with other attributes, it is overridden by them)

Usage

After a file upload is completed, you can get status information using file upload parameters. The status parameters use the cffile prefix; for example, cffile.clientDirectory. Status parameters can be used anywhere other ColdFusion parameters can be used.

Note: The file prefix is deprecated, in favor of the cffile prefix. Do not use the file prefix in new applications.

The following file upload status parameters are available after an upload.

Parameter | Description
attemptedServerFile | Initial name ColdFusion used when attempting to save a file
clientDirectory | Directory location of the file uploaded from the client’s system
clientFile | Name of the file uploaded from the client’s system
clientFileExt | Extension of the uploaded file on the client system (without a period)
clientFileName | Name of the uploaded file on the client system (without an extension)
contentSubType | MIME content subtype of the saved file
contentType | MIME content type of the saved file
dateLastAccessed | Date and time the uploaded file was last accessed
fileExisted | Whether the file already existed with the same path (Yes or No)
fileSize | Size of the uploaded file
fileWasAppended | Whether ColdFusion appended uploaded file to a file (Yes or No)
fileWasOverwritten | Whether ColdFusion overwrote a file (Yes or No)
fileWasRenamed | Whether uploaded file renamed to avoid a name conflict (Yes or No)
fileWasSaved | Whether Cold Fusion saves a file (Yes or No)
oldFileSize | Size of a file that was overwritten in the file upload operation
serverDirectory | Directory of the file saved on the server
serverFile | Filename of the file saved on the server
serverFileExt | Extension of the uploaded file on the server (without a period)
serverFileName | Name of the uploaded file on the server (without an extension)
timeCreated | Time the uploaded file was created
timeLastModified | Date and time of the last modification to the uploaded file

Tip: To refer to parameters, use the cffile prefix: for example, #cffile.fileExisted#.

Note: File status parameters are read-only. They are set to the results of the most recent cffile operation. (If two cffile tags execute, the results of the second overwrite the first.)

Example

The following example creates a unique filename, if there is a name conflict when the file is uploaded on Windows:

<cffile action = "upload"
   fileField = "FileContents"
   destination = "c:\web\uploads\"
   accept = "text/html"
   nameConflict = "MakeUnique">

The following examples show the use of the mode attribute. The first example creates the file /tmp/foo with permissions defined as: owner=read/write, group=read, other=read.

<cffile action = "write"
file = "/tmp/foo"
mode = 644
output = "some text">

This example appends to a file and sets permissions to read/write (rw) for all.

<cffile action = "append"
destination = "/home/tomj/testing.txt"
mode = 666
output = "Is this a test?">

This example uploads a file and sets permissions to owner/group/other = read/write/execute.

<cffile action = "upload"
fileField = "fieldname"
destination = "/tmp/program.exe"
mode = 777>


cffile action = "move"

Description

Moves a file from one location to another on the server.

Syntax

<cffile
   action = "move"
   source = "full_path_name"
   destination = "full_path_name"
   mode = "mode"
   attributes = "file_attributes_list"
   charset = "charset_option">

See also

cfdirectory

History

New in ColdFusion MX: this action attribute option supports the charset attribute.

New in ColdFusion MX: A directory path that you specify in the destination attribute does not require a trailing slash.

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system options of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
source
Required
Absolute pathname of file on web server.
On Windows, use backward slashes; on UNIX, use forward slashes.
destination
Required
Absolute pathname of directory or file on web server.
ColdFusion 5 and earlier: trailing slash in directory path is required. ColdFusion MX: trailing slash in directory path is optional. On Windows, use backward slashes; on UNIX, use forward slashes.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of UNIX chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal
charset
Optional
UTF-8
A Java character set name for the file contents. The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Example

The following example moves the keymemo.doc file from the c:\files\upload\ directory to the c:\files\memo\ directory on Windows:

<cffile
   action = "move"
   source = "c:\files\upload\keymemo.doc"
   destination = "c:\files\memo\">

In this example, the destination directory is "memo."


cffile action = "rename"

Description

Renames a file on the server.

Syntax

<cffile
   action = "rename"
   source = "full_path_name"
   destination = "full_path_name"
   mode = "mode"
   attributes = "file_attributes_list">

See also

cfdirectory

History

New in ColdFusion MX: a directory path that you specify in the destination attribute does not require a trailing slash.

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system options of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
source
Required
Absolute pathname of file on web server.
On Windows, use backward slashes; on UNIX, use forward slashes.
destination
Required
Absolute pathname of file on web server.
On Windows, use backward slashes; on UNIX, use forward slashes.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of UNIX chmod command. Assigned to owner, group, and other. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal

Example

The following example renames the file keymemo.doc to oldmemo.doc:

<cffile action = "rename"
   source = "c:\files\memo\keymemo.doc"
   destination = "c:\files\memo\oldmemo.doc">


cffile action = "copy"

Description

Copies a file from one directory to another on the server.

Syntax

<cffile
   action = "copy"
   source = "full_path_name"
   destination = "full_path_name"
   mode = "mode"
   attributes = "file_attributes_list">

See also

cfdirectory

History

New in ColdFusion MX: a directory path that you specify in the destination attribute does not require a trailing slash.

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system options of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
source
Required
Absolute pathname of file on web server.
On Windows, use backward slashes; on UNIX, use forward slashes.
destination
Required
Absolute pathname of directory or file on web server.
ColdFusion 5 and earlier: trailing slash in directory path is required. ColdFusion MX: trailing slash in directory path is optional. On Windows, use backward slashes; on UNIX, use forward slashes.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of Unix chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal

Example

This example copies the keymemo.doc file to the c:\files\backup\ directory:

<cffile action = "copy"
source = "c:\files\upload\keymemo.doc"
destination = "c:\files\backup\">


cffile action = "delete"

Description

Deletes a file on the server.

Syntax

<cffile
   action = "delete"
   file = "full_path_name">

See also

cfdirectory

Attributes

Attribute | Req/Opt | Default | Description
action | Required |  | Type of file manipulation that the tag performs.
file | Required |  | Absolute pathname of file on web server. On Windows, use backward slashes; on UNIX, use forward slashes.

Example

The following example deletes the specified file:

<cffile action = "delete"
   file = "c:\files\upload\#Variables.DeleteFileName#">


cffile action = "read"

Description

Reads a text file on the server. The file is read into a dynamic, local parameter that you can use in the page. For example:

  • Read a text file; insert the file’s contents into a database
  • Read a text file; use the find and replace function to modify the file’s contents

Note: This action reads the file into a variable in the local Variables scope. It is not intended for use with large files, such as logs, because this can bring down the server.

Syntax

<cffile
   action = "read"
   file = "full_path_name"
   variable = "var_name"
   charset = "charset_option" >

See also

cfdirectory

New in ColdFusion MX: this action attribute option supports the charset attribute.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
file
Required
Absolute pathname of file.
On Windows, use backward slashes; on UNIX, use forward slashes.
variable
Required
Name of variable to contain contents of text file.
charset
Optional
UTF-8
The Java character set name used for the file contents.
The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/
O-charset-lang.html

Usage

The following example creates a variable named Message for the contents of the file message.txt:

<cffile          action = "read"
file = "c:\web\message.txt"
variable = "Message">

The variable Message can be used in the page. For example, you could display the contents of the message.txt file in the final web page as follows:

<cfoutput>#Message#</cfoutput>

ColdFusion supports functions for manipulating the contents of text files. You can also use the variable that is created by a cffile action = "read" operation in the ArrayToList and ListToArray functions.


cffile action = "readBinary"

Description

Reads a binary file (such as an executable or image file) on the serve, into a binary object parameter that you can use in the page. To send it through a web protocol (such as HTTP or SMTP) or store it in a database, first convert it to Base64 using the ToBase64 function.

Note: This action reads the file into a variable in the local Variables scope. It is not intended for use with large files, such as logs, because they can bring down the server.

Syntax

<cffile
   action = "readBinary"
   file = "full_path_name"
   variable = "var_name">

See also

cfdirectory

Attributes

Attribute | Req/Opt | Default | Description
action | Required |  | Type of file manipulation that the tag performs.
file | Required |  | Absolute pathname of file. On Windows, use backward slashes; on UNIX, use forward slashes.
variable | Required |  | Name of variable to contain contents of binary file.

Usage

You convert the binary file to Base64 to transfer it to another site.

Example

The following example creates a variable named aBinaryObj to contain the ColdFusion Server executable:

<cffile action = "readBinary"
file = "c:\cfusion\bin\cfserver.exe"
variable = "aBinaryObj">


cffile action = "write"

Description

Writes a text file on the server, based on dynamic content. You can create static HTML files from the content, or log actions in a text file.

Syntax

<cffile
   action = "write"
   file = "full_path_name"
   output = "content"
   mode = "permission"
   addNewLine = "Yes" or "No"
   attributes = "file_attributes_list"
   charset = "charset_option" >

See also

cfdirectory

History

New in ColdFusion MX: on Windows platforms, the attributes attribute values temporary, archive, and system are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

New in ColdFusion MX: this action attribute option supports the charset attribute.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
file
Required
Absolute pathname of file on web server.
On Windows, use backward slashes; on UNIX, use forward slashes.
output
Required
Content of the file to be created.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of Unix chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
addNewLine
Optional
Yes
  • Yes: appends newline character to text written to file
  • No
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal
charset
Optional
UTF-8
The Java character set name used for the file contents.
The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Example

This example creates a file with information a user entered in an HTML insert form:

<cffile action = "write"
   file = "c:\files\updates\#Form.UpdateTitle#.txt"
   output = "Created By: #Form.FullName#
   Date: #Form.Date#
   #Form.Content#">

If the user submitted a form with the following:

UpdateTitle = "FieldWork"
FullName = "World B. Frueh"
Date = "10/30/01"
Content = "We had a wonderful time in Cambridgeport."

ColdFusion would create a file named FieldWork.txt in the c:\files\updates\ directory and the file would contain the following text:

Created By: World B. Frueh
Date: 10/30/01
We had a wonderful time in Cambridgeport.

This example shows the use of the mode attribute for UNIX. It creates the file /tmp/foo with permissions rw-r--r-- (owner = read/write, group = read, other = read):

<cffile action = "write"
   file = "/tmp/foo"
mode = 644>

This example appends to the file and sets permissions to read/write (rw) for all:

<cffile action = "append"
   destination = "/home/tomj/testing.txt"
mode = 666
output = "Is this a test?">

This example uploads a file and gives it the permissions owner/group/other = read/write/execute):

cffile action = "upload"
   fileField = "fieldname"
destination = "/tmp/program.exe"
mode = 777>


cffile action = "append"

Description

Appends text to a text file on the server.

Syntax

<cffile
   action = "append"
   file = "full_path_name"
   output = "string"
   addNewLine = "Yes" or "No"
   attributes = "file_attributes_list">
   mode = "mode"
   charset = "charset_option" >

See also

cfdirectory

History

New in ColdFusion MX: on Windows platforms, the temporary, archive, and system options of the attributes attribute are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

New in ColdFusion MX: this action attribute option supports the charset attribute.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
Type of file manipulation that the tag performs.
file
Required
Absolute pathname of file on web server to which to append content of output attribute.
On Windows, use backward slashes; on UNIX, use forward slashes.
mode
Optional
Applies only to Solaris and HP-UX. Permissions. Octal values of Unix chmod command. Assigned to owner, group, and other, respectively. For example:
  • 644: Assigns read/write permission to owner; read permission to group and other
  • 777: Assigns read/write/execute permission to all
output
Required
String to append to the file.
addNewLine
Optional
Yes
  • Yes: appends newline character to text written to file
  • No
attributes
Optional
One attribute (Windows) or a comma-delimited list of attributes (other platforms) to set on the file.
If omitted, the file's attributes are maintained.
Each value must be specified explicitly. For example, if you specify attributes = "readOnly", all other attributes are overwritten.
  • readOnly
  • hidden
  • normal
charset
Optional
UTF-8
The Java character set name used for the file contents.
The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Example

This example appends a text string to the file fieldwork.txt:

<cffile action = "append"
   file = "c:\files\updates\fieldwork.txt"
output = "<b>But Davis Square is the place to be.</b>">


cfflush

Description

Flushes currently available data to the client.

Category

Data output tags, Page processing tags

Syntax

<cfflush
   interval = "integer number of bytes">

See also

cfcache , cfheader , cfinclude , cfsetting , cfsilent

Attributes

Attribute | Req/Opt | Default | Description
interval | Optional |  | Integer. Flushes output each time this number of bytes becomes available. HTML headers, and data that is already available when the tag is executed, are omitted from the count.

Usage

The first occurrence of this tag on a page sends back the HTML headers and any other available HTML. Subsequent cfflush tags on the page send only the output that was generated after the previous flush.

When you flush data, ensure that enough information is available, as some browsers might not respond if you flush only a small amount. Similarly, set the interval attribute for a few hundred bytes or more, but not thousands of bytes.

Use the interval attribute only when a large amount of output will be sent to the client, such as in a cfloop or a cfoutput of a large query. Using this form globally (such as in the Application.cfm file) might cause unexpected errors when CFML tags that modify HTML headers are executed.

Caution:Once you have used this tag on a page, any CFML function or tag on the page that modifies the HTML header causes an error. (These include: cfcontent, cfcookie, cfform, cfheader, cfhtmlhead, and cflocation.)

Using the cfset tag to set a cookie scope variable causes an error. Cookie errors can be caught with the cfcatch type = "Any" tag. Other errors can be caught with cfcatch type = "template".

Using the cfflush tag within a cfsavecontent tag (if the cfsavecontent tag has content) causes an error.

Note: Normally, the cferror tag discards the current output buffer and replaces it with the contents of the error page. The cfflush tag discards the current buffer. As a result, the Error.GeneratedContent variable resulting from a cferror tag after a cfflush contains any contents of the output buffer that has not been flushed. This content is not sent to the client. The content of the error page displays to the client after the bytes that have been sent.

The following example uses cfloop tags and the rand random number generating function to delay data display. It simulates a page that is slow to generate data.

Example

<h1>Your Magic numbers</h1>
<p>It will take us a little while to calculate your ten magic numbers.
It takes a lot of work to find numbers that truly fit your
personality. So relax for a minute or so while we do the hard
work for you.</p>
<H2>We are sure you will agree it was worth the short wait!</H2>
<cfflush>

<cfflush interval=10>
<!--- Delay Loop to make it seem harder --->
<cfloop index="randomindex" from="1" to="200000" step="1">
   <cfset random=rand()>
</cfloop>

<!--- Now slowly output 10 random numbers --->
<cfloop index="Myindex" from="1" to="10" step="1">
   <cfloop index="randomindex" from="1" to="100000" step="1">
      <cfset random=rand()>
   </cfloop>
   <cfoutput>
      Magic number number #Myindex# is:&nbsp;&nbsp;#RandRange(
100000, 999999)#<br><br>
   </cfoutput>
</cfloop>


cfform

Description

Builds a form with CFML custom control tags; these provide more functionality than standard HTML form input elements.

Category

Forms tags

Syntax

<cfform
   name = "name"
   action = "form_action"
   preserveData = "Yes" or "No"
   onSubmit = "javascript"
   target = "window_name"
   encType = "type"
   passThrough = "HTML_attribute(s)"
   codeBase = "URL"
   archive = "URL"
   scriptSrc = "path">
...
</cfform>

See also

cfapplet , cfgrid , cfinput , cfselect , cfslider , cftextinput , cftree , cftreeitem

History

New in ColdFusion MX: the enableCAB attribute is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.

New in ColdFusion MX: the name and action attributes are optional.

Attributes

Attribute
Req/Opt
Default
Description
name
Optional
CFForm_1
[, ...]
A name for the form.
action
Optional
Name of ColdFusion page to execute when the form is submitted for processing.
scriptSrc
Optional
/cfide/scripts/cfform.js
Lets the user control the URL of the script file; useful if you do not keep the file in the /cfide directory.
preserveData
Optional
No
When the cfform action attribute posts back to the same page as the form, this determines whether to override the control values with the submitted values.
  • false: values specified in the control tag attributes are used
  • true: corresponding submitted values are used
Applies to these controls:
  • cfform controls cfinput, cfslider, cftextinput; overrides value attribute value
  • cfselect controls that are populated from queries. Overrides the selected attribute. See cfselect.
  • cftree controls: Overrides the cftreeitem expand attribute. If true, expands previously-selected elements. The cftree completePath attribute must be set to Yes.
  • cfgrid controls: has no effect. (This avoids confusion as to whether data has been resubmitted to the database by the control.)
onSubmit
Optional
JavaScript function to execute after input validation. Use to for preprocessing data before form is submitted. See Developing ColdFusion MX Applications with CFML.
passThrough
Optional
For HTML attributes that are not supported by cfform. Attributes and values are passed to the HTML code that is generated for the tag.
For example:
"style=""font-weight:bold;"""
codeBase
Optional
See Description
URL of downloadable JRE plug-in (for Internet Explorer only).
Default: /CFIDE/classes/cf-j2re-win.cab
archive
Optional
See Description
URL of downloadable Java classes for ColdFusion controls.
Default: /CFIDE/classes/CFJava2.jar

Usage

This tag requires an end tag.

Some custom control tags that you can use within this tag require the client to download a Java applet; they might execute slightly more slowly than using an HTML form element to get the same information. In addition to regular HTML form elements, you can use the following custom control tags within the cfform tag:

  • cfinput: Creates and validates an input element (radio button, text box, checkbox)
  • cfselect: Creates a drop-down list box
  • cfslider: Creates a slider control (Java support required)
  • cftextinput: Creates a text input box (Java support required)
  • cftree: Creates a tree control (Java support required)
  • cfgrid: Creates a grid control to display tabular data (Java support required)
  • cfapplet: Embeds a registered Java applet (Java support required)

All of these control tags require that the browser is JavaScript-enabled.

If you use this tag after the cfflush tag on a page, an error is thrown.

The method attribute is automatically set to post; if you specify a value, it is ignored.

If you specify a value in quotation marks, you must escape them by doubling them; for example: passThrough = "readonly = ""Yes"" ".

Any form field name, from the cfform tag or an HTML form, that ends in one of the following suffixes invokes server-side form validation:

  • _integer: Verifies that the user entered a number.
  • _float: Verifies that the user entered a number.
  • _range: Verifies that a numeric value entered is within specified boundaries.
  • _date: Verifies that the user entered a date; converts to ODBC date format.
  • _time: Verifies that the user correctly entered a time; converts to ODBC time format.
  • _eurodate: Verifies that the user entered a date in a standard European date format; converts to ODBC date format.

Do not use these suffixes for your field names.

For more information, see the Retrieving and Formatting Data chapter in Developing ColdFusion MX Applications with CFML.


Incorporating HTML form tags

The cfform tag lets you incorporate these standard HTML elements:

  • Standard form tag attributes and values. The attributes and values are included in the form tag that cfform outputs in the page. For example, you can use form tag attributes like target with cfform. Other pass-through attributes include CLASS, ENCTYPE, ID, ONLOAD, ONRESET, and STYLE.
  • HTML tags that can ordinarily be put within the HTML form tag. For example, you can use the HTML input tag to create a submit button in a cfform, without the other features of cfinput:
    • <cfform>
   <input type = "Submit" value = " update... ">
</cfform>

Example

<h3>cfform Example</h3>
<cfif IsDefined("form.oncethrough") is "Yes">
   <cfif IsDefined("form.testVal1") is True>
   <h3>Results of Radio Button Test</h3>
   <cfif form.testVal1 is "Yes">Your radio button answer was yes</cfif>
   <cfif form.testVal1 is "No">Your radio button answer was no</cfif>
   </cfif>
   <cfif IsDefined("form.chkTest2") is True>
   <h3>Results of Checkbox Test</h3>
      Your checkbox answer was yes
   <cfelse>
      <h3>Results of Checkbox Test</h3>
      Your checkbox answer was no
   </cfif>
   <cfif IsDefined("form.textSample") is True
    AND form.textSample is not "">
   <h3>Results of Credit Card Input</h3>
      Your credit card number, <cfoutput>#form.textSample#</cfoutput>,
was valid under the MOD 10 algorithm.
   </cfif>
   <cfif IsDefined("form.sampleSlider") is "True">
   <h3>You gave this page a rating of <cfoutput>#form.sampleSlider#
   </cfoutput></h3>
   </cfif>
   <hr noshade>
</cfif>
<!--- begin by calling the cfform tag --->
<cfform action = "cfform.cfm">
<table>
<tr>
   <td>
   <h4>This example displays radio button input type for cfinput.</h4>
   Yes <cfinput type = "Radio" name = "TestVal1" value = "Yes" checked>
   No <cfinput type = "Radio" name = "TestVal1" value = "No">
   </td>
</tr>
<tr>
   <td>
   <h4>This example displays checkbox input type for cfinput.</h4>
   <cfinput type = "Checkbox" name = "ChkTest2" value = "Yes">
   </td>
</tr>
<tr>
   <td>
   <h4>This shows client-side validation for cfinput text boxes.</h4>
   <br>(<I>This item is optional</i>)<br>
   Please enter a credit card number:
   <cfinput type = "Text" name = "TextSample"
      message = "Please enter a Credit Card Number"
      validate = "creditcard" required = "No">
   </td>
</tr>
<tr>
   <td>
   <h4>This example shows the use of the cfslider tag.</h4>
   <p>Rate your approval of this example from 1 to 10 by sliding control.
   <p>1 <cfslider name = "sampleSlider"
         label = "Sample Slider" range = "1,10"
         message = "Please enter a value from 1 to 10"
         scale = "1" bold = "No"
         italic = "No" refreshlabel = "No"> 10
   </td>
</tr>
</table>
<p><input type = "submit" name = "submit" value = "show me the result">
<input type = "hidden" name = "oncethrough" value = "Yes">
</cfform>
</body>
</html>


cfftp

Description

Lets users implement File Transfer Protocol (FTP) operations.

Category

File management tags, Internet Protocol tags

Syntax

The tag syntax depends on the action attribute value. See the following sections:

  • cfftp: Connecting to an FTP server
  • cfftp: Connection caching
  • cfftp: Connection: File and directory operations
  • cfftp action = "listDir"

See also

cfhttp , cfldap , cfmail , cfpop

Usage

Use this tag to move files between a ColdFusion server and an FTP server.

This tag does not move files between a ColdFusion server and a client browser. You do this as follows:

  • To transfer files from a client to a ColdFusion server: cffile action = "upload"
  • To transfer files from a ColdFusion server to a client: the cfcontent tag


Security settings

ColdFusion Server Basic security settings can prevent the cfftp tag from executing. If you run ColdFusion applications on a server that is used by multiple customers, consider the security of the files that the customer can move. For more information, see Administering ColdFusion MX.


cfftp: Connecting to an FTP server

Description

To establish a connection with an FTP server, you use the connection attribute.

Syntax

<cfftp
   action = "action"
   username = "name"
   password = "password"
   server = "server"
   timeout = "timeout in seconds"
   port = "port"
   connection = "name"
   proxyServer = "proxyserver"
   retryCount = "number"
   stopOnError = "Yes" or "No"
   passive = "Yes" or "No">

See also

cfhttp , cfldap , cfmail , cfpop

Attributes

Attribute
Req/Opt
Default
Description
action
Required
FTP operation to perform.
  • open: create an FTP connection
  • close: terminate an FTP connection
For more information, see cfftp: Connection caching.
username
Required if action = "open"
User name to pass in the FTP operation.
password
Required if action = "open"
Password to log in the user.
server
Required if action = "open"
FTP server to which to connect; for example, ftp.myserver.com
timeout
Optional
30
Value in seconds for the timeout of all operations, including individual data request operations.
port
Optional
21
Remote port to which to connect.
connection
Optional
Name of the FTP connection. Used to cache a new FTP connection or to reuse a connection. If you specify the username, password, and server attributes, and if no connection exists for them, ColdFusion creates one. Calls to cfftp with the same connection name reuse the connection information.
proxyServer
Optional
String. Name of proxy server (or servers) to use, if proxy access is specified.
retryCount
Optional
1
Number of retries until failure is reported.
stopOnError
Optional
No
  • Yes: halts processing, displays an appropriate error.
  • No: populates these variables:
    • cfftp.succeeded – Yes or No.
    cfftp.errorCode – Error number. See the IETF Network Working Group RFC 959: File Transfer Protocol (FTP): www.ietf.org/rfc/rfc0959.txt.
    cfftp.errorText – Message text
For conditional operations, use cfftp.errorCode. Do not use cfftp.errorText for this purpose.
passive
Optional
No
  • Yes: enable passive mode
  • No

Usage

If you use connection caching to an active FTP connection, you do not have to respecify the username, password, or server connection attributes:

Changing a cached connection, such as changing retryCount or timeout values, might require reestablishing the connection.

Example

<p>cfftp lets users implement File Transfer Protocol operations.
By default, cfftp caches an open connection to an FTP server.
<p>cfftp operations are usually of two types:
<ul>
   <li>Establishing a connection
   <li>Performing file and directory operations
</ul>
<p>This example opens and verifies a connection, lists the files in a
directory, and closes the connection.
<p>Open a connection
<cfftp action = "open"
   username = "anonymous"
   connection = "My_query"
   password = "youremail@email.com"
   server = "ftp.tucows.com"
   stopOnError = "Yes">
<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput>
<p>List the files in a directory:
<cfftp action = "LISTDIR"
    stopOnError = "Yes"
    name = "ListFiles"
    directory = "/"
    connection = "my_query">
<cfoutput query = "ListFiles">
   #name#<br>
</cfoutput>

<p>Close the connection:
<cfftp action = "close"
connection = "My_query"
stopOnError = "Yes">
<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput>


cfftp: Connection caching

Description

After you establish a connection with cfftp, you can reuse it to perform additional FTP operations. To do this, you use the connection attribute to define and name an FTP connection object that stores information about the connection. Any FTP operations that use the same connection name automatically use the information stored in the connection object. This helps save connection time and improves file transfer performance.

Usage

To keep the connection open throughout a session or longer, you can use a session or application variable as the connection name. However, if you do this, you must specify the full variable name, with the close action, when you are finished. Keeping a connection open prevents others from using the FTP server; so close a connection as soon as possible.

Changes to a cached connection, such as changing retryCount or timeout values, might require reestablishing the connection.

Example

The following example opens a connection and gets a file listing showing file or directory name, path, URL, length, and modification date.

<p>Open a connection
<cfftp connection = "myConnection"
   username = "myUserName"
  password = "myUserName@allaire.com"
  server = "ftp.allaire.com"
   action = "open"
   stopOnError = "Yes">

<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput>
<cfftp connection = "myConnection"
    action = "LISTDIR"
    stopOnError = "Yes"
    name = "ListDirs"
    directory = "/">

<p>FTP Directory Listing:<br>
<cftable query = "ListDirs" HTMLTable = "Yes" colHeaders = "Yes">
   <cfcol header = "<b>Name</b>" text = "#name#">
   <cfcol header = "<b>Path</b>" text = "#path#">
   <cfcol header = "<b>URL</b>" text = "#url#">
   <cfcol header = "<b>Length</b>" text = "#length#">
   <cfcol header = "<b>LastModified</b>"
    text = "Date(Format#lastmodified#)">
   <cfcol header = "<b>IsDirectory</b>" text = "#isdirectory#">
</cftable>

<p>Close the connection:
<cfftp connection = "myConnection"
    action = "close"
    stopOnError = "Yes">
<p>Did it succeed? <cfoutput>#cfftp.succeeded#</cfoutput>


cfftp: Connection: File and directory operations

Description

Use this form of the cfftp tag to perform file and directory operations with cfftp.

Syntax

<cfftp
   action = "action"
   username = "name"
   password = "password"
   name = "query_name"
   server = "server"
   ASCIIExtensionList = "extensions"
   transferMode = "mode"
   failIfExists = "Yes" or "No"
   directory = "directory name"
   localFile = "filename"
   remoteFile = "filename"
   item = "directory or file"
   existing = "file or directory name"
   new = "file or directory name"
   proxyServer = "proxyserver"
   passive = "Yes" or "No">

See also

cfhttp , cfldap , cfmail , cfpop

Attributes

Attribute
Req/Opt
Default
Description
action
Required if connection is not cached
FTP operation to perform.
  • changedir
  • createDir
  • listDir
  • removeDir
  • getFile
  • putFile
  • rename
  • remove
  • getCurrentDir
  • getCurrentURL
  • existsDir
  • existsFile
  • exists
username
Required if connection is not cached
User name to pass in the FTP operation.
password
Required if action = "open"
Password to log in the user.
name
Required if action = "listDir"
Query name of directory listing.
server
Required if FTP connection is not cached
FTP server to which to connect; for example, ftp.myserver.com.
ASCIIExtensionList
Optional
txt;htm;html;cfm;cfml;
shtm;shtml;
css;asp;asa
Delimited list of file extensions that force ASCII transfer mode, if transferMode = "auto".
transferMode
Optional
Auto
  • ASCII FTP transfer mode
  • Binary FTP transfer mode
  • Auto FTP transfer mode
failIfExists
Optional
Yes
  • Yes: if a local file with same name exists, getFile fails
  • No
directory
Required if action = "changedir", "createDir", "listDir", or "existsDir"
Directory on which to perform an operation.
localFile
Required if action = "getFile" or putFile
Name of the file on the local file system.
remoteFile
Required if action = "getFile", "putFile", or "existsFile"
Name of the file on the FTP server file system.
item
Required if action = "exists" or "remove"
Object of these actions: file or directory.
existing
Required if action = "rename"
Current name of the file or directory on the remote server.
new
Required if action = "rename"
New name of file or directory on the remote server
proxyServer
Optional
String. Name of the proxy server (s) to use, if proxy access is specified
passive
Optional
No
  • Yes: enable passive mode
  • No

Usage

If you use connection caching to an active FTP connection, you do not have to respecify the username, password, or server connection attributes:

Changing a cached connection, such as changing retryCount or timeout values, might require reestablishing the connection.

If action = "listDir", the attributes column returns directory or normal. Other platform-specific values, such as hidden and system, are no longer supported.

If action = "listDir", a mode column is returned. The column contains an octal string representation of UNIX permissions; for example, "777."

The cfftp.returnValue variable provides the return value for these actions:

  • getCurrentDir
  • getCurrentURL
  • existsDir
  • existsFile
  • exists

For more information, see Developing ColdFusion MX Applications with CFML.

Caution:Object (file and directory) names are case-sensitive.


Action (cfftp.ReturnValue variable)

The results of an action determine the value of the cfftp.returnValue variable.

cfftp action | Value of cfftp.returnValue
getCurrentDir | String. Current directory.
getCurrentURL | String. Current URL.
existsDir | Yes or No.
existsFile | Yes or No.
exists | Yes or No.


cfftp action = "listDir"

Description

To access the columns in a query object, use this tag with action = "listDir".

Usage

When you use this action, you must specify a value for the name attribute. This value holds the results of the listDir action in a query object. The query object consists of columns that you can reference, in the form queryname.columname[row], where queryname is the name of the query, specified in the name attribute; and columnname is a column returned in the query object. The value row is the row number of each file/directory entry returned by the listDir operation. A separate row is created for each entry:

cfftp query object column | Description
Name | Filename of the current element.
Path | File path (without drive designation) of the current element.
URL | Complete URL for the current element (file or directory).
Length | File size of the current element.
LastModified | Unformatted date/time value of the current element.
Attributes | String. Attributes of the current element: normal or Directory.
IsDirectory | Boolean. Whether object is a file or directory.
Mode | Applies only to Solaris and HP-UX. Permissions. Octal string.

Note: Previously supported query column values that pertain to system-specific information are not supported; for example, hidden and system.


cffunction

Description

Defines functionality that you build in CFML.

Category

Extensibility tags

Syntax

<cffunction
   name = "methodName"
   returnType = "dataType"
   roles = "securityRoles"
   access = "methodAccess"
   output = "yes" or "no" >

See also

cfargument , cfcomponent , cfinvoke , cfinvokeargument , cfobject , cfproperty , cfreturn

Attributes

Attribute
Req/Opt
Default
Description
name
Required
A string; a component method that is used within the cfcomponent tag.
returnType
Required for a web service; Optional, otherwise.
any
String; a type name; data type of the function return value.
  • any
  • array
  • binary
  • boolean
  • date
  • guid
  • numeric
  • query
  • string
  • struct
  • uuid
  • variableName
  • void (this option does not return a value)
  • a return type
If the value is not a recognized type, ColdFusion processes it as a component name.
roles
Optional
"" (empty)
This attribute is used only for a component.
A comma-delimited list of ColdFusion security roles that can invoke the method. If this attribute is omitted, all roles can invoke the method.
access
Optional
public
This attribute is used only for a component.
The client security context from which the method can be invoked:
  • private: available only to the component that declares the method
  • package: available only to the component that declares the method or to another component in the package
  • public: available to a locally executing page or component method
  • remote: available to a locally or remotely executing page or component method, or a remote client through a URL, Flash, or a web service. To publish the function as a web service, this option is required.
output
Optional
Function is processed as standard CFML
This attribute is used only for a component.
  • yes: the function is processed as if it were within a cfoutput tag
  • no: the function is processed as if it were within a cfsilent tag

Usage

Components that are stored in the same directory are members of a component package.

Within a cffunction tag, if you specify the roles attribute, the method executes only if a user is logged in and belongs to one of the specified roles.

For more information, see the "Building and Using ColdFusion Components" chapter in Developing ColdFusion MX Applications with CFML.

The following example shows a typical use of this tag:

<cffunction
   name="getEmployees"
   access="remote"
   returnType="query"
   hint="This query returns all records in the employee database. It can
drill-down or narrow the search, based on optional input parameters.">

Example

<cfcomponent>
   <cffunction name="getEmp">
       <cfquery
            name="empQuery" datasource="ExampleApps" >
            SELECT FIRSTNAME, LASTNAME, EMAIL
            FROM tblEmployees
       </cfquery>
       <cfreturn empQuery>
   </cffunction>
   <cffunction name="getDept">
      <cfquery
name="deptQuery" datasource="ExampleApps" >
          SELECT *
          FROM tblDepartments
       </cfquery>
       <cfreturn deptQuery>
   </cffunction>
</cfcomponent>


cfgraph

Description

This tag is deprecated. Use the cfchart, cfchartdata, and cfchartseries tags instead.

Displays data graphically.

History

New in ColdFusion MX: this tag is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.

The incompatibilities between the ColdFusion MX implementation and earlier implementations of this tag are as follows:

cfgraph tag attribute
ColdFusion MX functionality
Title
Ignored
Titlefont
Ignored
Barspacing
Ignored
Bordercolor
Color used for border, gridlines, and text displays
Colorlist
  • Pie chart: list of colors to use for each data point
  • Other chart types: ignored
Valuelabelfont
Sets value label text font. If the Valuelabelfont, Itemlabelfont, and Legendfont values differ, ColdFusion uses the last value that you specify in the tag.
Arial is not supported; it is mapped to Dialog.
Itemlabelfont
Sets item label text font. If the Valuelabelfont, Itemlabelfont, and Legendfont values differ, ColdFusion uses the last value that you specify in the tag
Arial is not supported; it is mapped to Dialog.
Legendfont
Sets legend text font. If the Valuelabelfont, Itemlabelfont, and Legendfont values differ, ColdFusion uses the last value that you specify in the tag
Arial is not supported; it is mapped to Dialog.
ShowLegend
  • above, below, left, right: these options cause the legend to display, but have no effect on its location.
  • none: prevents display of a legend
Valuelabelsize
Sets value label text size. If the Valuelabelsize and Itemlabelsize values differ, ColdFusion uses the last value that you specify in the tag
Itemlabelsize
Sets item label text size
Itemlabelorientation
Ignored. ColdFusion calculates best orientation based on label and graph size.
Borderwidth
  • a non-zero number: default-width border, regardless of number value
  • 0: no border
Depth
  • 0: displays graph with two-dimensional appearance
  • any other value: displays graph with threedimensional appearance
Linewidth
Ignored
Showvaluelabel
  • yes: displays values on mouse-click;
  • no: suppresses value displays
  • rollover: displays values on mouse-over.
Valuelocation
Ignored
url
URL of page to open if any item in the graph is clicked.
The following variables may be used within the URL; they are substituted with real values before the URL is accessed:
  • "$value$": selected row/column value or an empty string
  • "$itemlabel$": selected item (column) value or an empty string
  • "$serieslabel$": selected series (row) value or an empty string
  • "javascript:...": executes client side scripts.
Urlcolumn
Ignored.
This attribute generates a graph, but the url link is missing data that the linked page may expect. Thus, drilling-down in the graph may result in an error.
Type="HorizontalBar"
The (0,0) coordinate is located at the lower-left.
ScaleFrom
If the smallest value in the data is less than scaleFrom or the largest value in the data is greater than scaleTo, the respective data value is used as the minimum or maximum on the Y scale. Therefore, regardless of the scaleFrom or scaleTo value, all data values display.


cfgraphdata

Description

This tag is deprecated. Use the cfchart, cfchartdata, and cfchartseries tags instead.

Displays a data point in a graph. Used within the cfgraph tag.

History

New in ColdFusion MX: this tag is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.


cfgrid

Description

Used within the cfform tag. Puts a grid control (a table of data) in a ColdFusion form. To specify grid columns and row data, use the cfgridcolumn and cfgridrow tags, or use the query attribute, with or without cfgridcolumn tags.

Category

Forms tags

Syntax

<cfgrid
   name = "name"
   height = "integer"
   width = "integer"
   autoWidth = "Yes" or "No"
   vSpace = "integer"
   hSpace = "integer"
   align = "value"
   query = "query_name"
   insert = "Yes" or "No"
   delete = "Yes" or "No"
   sort = "Yes" or "No"
   font = "column_font"
   fontSize = "size"
   italic = "Yes" or "No"
   bold = "Yes" or "No"
   textColor = "web color"
   href = "URL"
   hrefKey = "column_name"
   target = "URL_target"
   appendKey = "Yes" or "No"
   highlightHref = "Yes" or "No"
   onValidate = "javascript_function"
   onError = "text"
   gridDataAlign = "position"
   gridLines = "Yes" or "No"
   rowHeight = "pixels"
   rowHeaders = "Yes" or "No"
   rowHeaderAlign = "position"
   rowHeaderFont = "font_name"
   rowHeaderFontSize = "size"
   rowHeaderItalic = "Yes" or "No"
   rowHeaderBold = "Yes" or "No"
   rowHeaderTextColor = "web color"
   colHeaders = "Yes" or "No"
   colHeaderAlign = "position"
   colHeaderFont = "font_name"
   colHeaderFontSize = "size"
   colHeaderItalic = "Yes" or "No"
   colHeaderBold = "Yes" or "No"
   colHeaderTextColor = "web color"
   bgColor = "web color"
   selectColor = "web color"
   selectMode = "mode"
   maxRows = "number"
   notSupported = "text"
   pictureBar = "Yes" or "No"
   insertButton = "text"
   deleteButton = "text"
   sortAscendingButton = "text"
   sortDescendingButton = "text">
</cfgrid>

See also

cfapplet , cfform , cfinput , cfselect , cfslider , cftextinput , cftree , cftreeitem

History

New in ColdFusion MX: ColdFusion does not use the rowHeaderWidth attribute. You can omit it.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of grid element.
height
Optional
300
Height of grid control, in pixels.
width
Optional
300
Width of grid control, in pixels.
autoWidth
Optional; see description
No
  • Yes: sets column widths so that all columns display within grid width.
  • No: sets columns to equal widths. User can resize columns. Horizontal scroll bars are not available, because if you specify a column width and set autoWidth = "Yes", ColdFusion sets to this width, if possible.
vSpace
Optional
Vertical space above and below grid control, in pixels.
hSpace
Optional
Horizontal space to left and right of grid control, in pixels.
align
Optional
Alignment of the grid cell contents:
  • Top
  • Left
  • Bottom
  • Baseline
  • Texttop
  • Absbottom
  • Middle
  • Absmiddle
  • Right
query
Optional
Name of query associated with grid control.
insert
Optional
No
  • Yes: user can insert row data in grid. Takes effect only if selectmode="edit"
  • No
delete
Optional
No
  • Yes: user can delete row data from grid. Takes effect only if selectmode="edit"
  • No
sort
Optional
No
The sort button performs simple text sort on column. User can sort columns by clicking column head or by clicking sort buttons. Not valid with selectmode=browse.
  • Yes: sort buttons display on grid control
  • No
font
Optional
Font of column data in the grid control.
fontSize
Optional
Size of text in the grid control, in points.
italic
Optional
No
  • Yes: displays grid control text in italic
  • No
bold
Optional
No
  • Yes: displays grid control text in bold
  • No
textColor
Optional
Black
Color of text in grid control; hex or text.
Hex value or supported named color; see name list in the Usage section.
For a hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
For a list of the supported named colors, see cfchart.
href
Optional
URL o r query column name that contains a URL to hyperlink each grid cell with.
hrefKey
Optional
The query column to use for the value appended to the href URL of each cell, instead of the cell's value.
target
Optional
Target of href URL.
appendKey
Optional
Yes
  • Yes: When used with href, appends "GFGRIDKEY=" and the value of the cell to each cell's URL.
  • No
highlightHref
Optional
Yes
  • Yes: highlights links associated with a cfgrid with an href attribute value
  • No
onValidate
Optional
A JavaScript function to validate user input. The form object, input object, and input object value are passed to routine, which returns True if validation succeeds; False otherwise.
onError
Optional
A JavaScript function to execute if validation fails.
gridDataAlign
Optional
Left
  • Left: left-aligns data within column.
  • Right: right-aligns data within column.
  • Center: center-aligns data within column.
gridLines
Optional
Yes
  • Yes: enables row and column rules in grid control
  • No
rowHeight
Optional
Minimum row height, in pixels, of grid control. Used with cfgridcolumn type = "Image"; defines space for graphics to display in row.
rowHeaders
Optional
Yes
  • Yes: displays a column of numeric row labels in grid control
  • No
rowHeaderAlign
Optional
Left
  • Left: left-aligns data within row header
  • Right: right-aligns data within row header
  • Center: center-aligns data within row header
rowHeaderFont
Optional
Row label font.
rowHeaderFontSize
Optional
Row label text size in grid control, in points.
rowHeaderItalic
Optional
No
  • Yes: displays row label text in italic
  • No
rowHeaderBold
Optional
No
  • Yes: displays row label text in bold
  • No
rowHeaderTextColor
Optional
Black
Text color of grid control row headers.
  • Options: same as for textColor attribute
colHeaders
Optional; see description
Yes
  • Yes: displays column headers in grid control
  • No
colHeaderAlign
Optional
Left
  • Left
  • Right
  • Center
colHeaderFont
Optional
Font of column header in grid control.
colHeaderFontSize
Optional
Size of column header text in grid control, in points.
colHeaderItalic
Optional
No
  • Yes: displays column headers in italics
  • No
colHeaderBold
Optional
No
  • Yes: displays column headers in bold
  • No
colHeaderTextColor
Optional
Color of grid control column headers.
  • Options: same as for textColor attribute
bgColor
Optional
Background color of grid control.
  • Options: same as for textColor attribute
selectColor
Optional
Background color for a selected item.
  • Options: same as for textColor attribute
selectMode
Optional
Browse
Selection mode for items in grid control.
  • Edit: user can edit grid data. Selecting a cell opens the editor for the cell type.
  • Single: user selections are limited to selected cell.
  • Row: user selections automatically extend to the row that contains selected cell.
  • Column: user selections automatically extend to column that contains selected cell.
  • Browse: user can only browse grid data
maxRows
Optional
Maximum number of rows to display in grid.
notSupported
Optional
(See Description)
Text to display if page that contains Java applet-based cfform control is opened by a browser that does not support Java or has Java support disabled.
Default: "<b> Browser must support Java to view ColdFusion Java Applets</b>"
pictureBar
Optional
No
  • Yes: images for Insert, Delete, Sort buttons
  • No
insertButton
Optional
Insert
Insert button. Takes effect only if selectmode="edit".
deleteButton
Optional
Delete
Text of Delete button text. Takes effect only if selectmode="edit".
sortAscendingButton
Optional
A -> Z
Sort button text
sortDescendingButton
Optional
Z -> A
Sort button text

Usage

You can populate a cfgrid with data from a cfquery. If you do not specify any cfgridcolumn entries, ColdFusion generates a default set of columns, which includes each column in the query. A default header for each column is created by replacing hyphen or underscore characters in the table column name with spaces. The first character, and any character after a space, are changed to uppercase; all other characters are lowercase.

This tag requires the client to download a Java applet; therefore, this tag might be slightly slower than using an HTML form element or the cfinput tag to get the same information.

For this tag to work properly. the browser must be JavaScript-enabled.

This tag requires an end tag.


How data is returned from cfgrid

This tag returns data by setting form variables in the data submitted to the form's action page, as an HTML form control does. Because the data can vary, depending on the tag’s SelectMode attribute value, the form variables that are returned also vary depending on this value.

In general, the data returned falls into one of these categories:

  • Simple data, returned from simple select operations
  • Complex data, returned from insert, update and delete operations


Simple selection data (SelectMode = Single, Column, or Row)

The data that form variables return to the cfform's action page contains information about which cells the user selected. In general, ColdFusion makes this data available in the action page, as ColdFusion variables in the Form scope, with the naming convention form.#GridName#.#ColumnName#

Each SelectMode returns these form variable(s):

  • SelectMode="single"

    • form.#GridName#.#ColumnName# = "SelectedCellValue"

  • SelectMode="column"

    • form.#GridName#.#ColumnName# = "ValueOfCellRow1,
    ValueOfCellRow2, ValueOfCellRowN"

  • SelectMode="row"

    • form.#GridName#.#Column1Name# ="ValueOfCellInSelectedRow"
    form.#GridName#.#Column2Name# = "ValueOfCellInSelectedRow"
    form.#GridName#.#ColumnNName# = "ValueOfCellInSelectedRow"


Complex update data (SelectMode = Edit)

The grid returns a large amount of data, to inform the action page of inserts, updates or deletes that the user made to the grid. In most cases, you can use the cfgridupdate tag to automatically gather the data from the form variables; the tag collects data, writes SQL calls, and updates the data source.

If you cannot use cfgridupdate (if, for example, you must distribute the returned data to more than one data source), you must write code to read form variables. In this mode, ColdFusion creates the following array variables in the Form scope for each cfgrid:

form.#GridName#.#ColumnName#
form.#GridName#.original.#ColumnName#
form.#GridName#.RowStatus.Action

Each table row that contains an update, insert, or deletion has a parallel entry in each of these arrays. To view all the information for all the changes, you can traverse the arrays, as in this example:

<cfloop index="ColName" list="#ColNameList#">
   <cfif IsDefined("form.#GridName#.#ColName#")>
      <cfoutput><br>form.#GridName#.#ColName#:<br></cfoutput>

      <cfset Array_New = evaluate("form.#GridName#.#ColName#")>
      <cfset Array_Orig = evaluate("form.#GridName#.original.#ColName#")>
      <cfset Array_Action = evaluate("form.#GridName#.RowStatus.Action")>

      <cfif NOT IsArray(Array_New)>
         <b>The form variable is not an array!</b><br>
      <cfelse>
         <cfset size = ArrayLen(Array_New)>
         <cfoutput>
         Result Array Size is #size#.<br>
         Contents:<br>
         </cfoutput>

         <cfif size IS 0>
            <b>The array is empty.</b><br>
         <cfelse>
            <table BORDER="yes">
               <tr>
                  <th>Loop Index</TH>
                  <th>Action</TH>
                  <th>Old Value</TH>
                  <th>New Value</TH>
               </tr>
               <cfloop index="LoopCount" from="1" to=#size#>
                   <cfset Val_Orig   = Array_Orig[#LoopCount#]>
                   <cfset Val_New    = Array_New[#LoopCount#]>
               <cfset Val_Action   = Array_Action[#LoopCount#]>
               <cfoutput>
               <tr>
                  <td>#LoopCount#</td>
                  <td>#Val_Action#</td>
                  <td>#Val_Orig#</td>
                  <td>#Val_New#</td>
               </tr>
               </cfoutput>
               </cfloop>
            </table>
         </cfif>
      </cfif>
   <cfelse>
      <cfoutput>form.#GridName#.#ColName#: NotSet!</cfoutput><br>
   </cfif>
</cfloop>


Using the href attribute

When specifying a URL with grid items using the href attribute, the selectMode attribute value determines whether the appended key value is limited to one grid item or extends to a grid column or row. When a user clicks a linked grid item, a cfgridkey variable is appended to the URL, in this form:

http://myserver.com?cfgridkey = selection

If the appendKey attribute is set to No, no grid values are appended to the URL.

The value of selection is determined by the value of the selectMode attribute:

  • If selectMode = "Single", selection is the value of the column clicked.
  • If selectMode = "Row", selection is a delimited list of column values in the clicked row, beginning with the value of the first cell in the row.
  • If selectMode = "Column", selection is a delimited list of row values in the clicked column, beginning with the value of the first cell in the column.

Clicking the submit button while editing a grid cell occasionally causes the cell changes to be lost. To ensure that changes are submitted properly, Macromedia recommends that after user updates data in a cell, they click another cell before submitting the form.

Example

<!--- This shows cfgrid, cfgridcolumn, cfgridrow, and cfgridupdate --->
<!--- use a query to show the useful qualities of cfgrid --->
<!--- If the gridEntered form field has been tripped, perform gridupdate
on table specified in database. Using default value keyonly = yes
lets us change only information that differs from previous grid --->
<cfif IsDefined("form.gridEntered") is True>
   <cfgridupdate grid = "FirstGrid" dataSource = "cfsnippets"
   tableName = "CourseList" keyOnly = "Yes">
</cfif>
<!--- query the database to fill up the grid --->
<cfquery name = "GetCourses" dataSource = "cfsnippets">
SELECT Course_ID, Dept_ID, CorNumber,
     CorName, CorLevel, CorDesc
FROM  CourseList
ORDER by Dept_ID ASC, CorNumber ASC
</cfquery>

<html>
<head>
<title>cfgrid Example</title>
</head>
<body>
<h3>cfgrid Example</h3>
<I>Try adding a course to the database, and then deleting it.</i>
<!--- call the cfform to allow us to use cfgrid controls --->
<cfform action = "cfgrid.cfm">
<!--- We include Course_ID in cfgrid, but do not allow selection or display --->
<!--- cfgridcolumn tags are used to change the parameters involved in
displaying each data field in the table--->
<cfgrid name = "FirstGrid" width = "450"
   query = "GetCourses" insert = "Yes" delete = "Yes" sort = "Yes"
   font = "Tahoma" bold = "No" italic = "No" appendKey = "No" highlightHref = "No"
   gridDataAlign = "LEFT" gridLines = "Yes"rowHeaders = "Yes"
   rowHeaderAlign = "LEFT"    rowHeaderItalic = "No" rowHeaderBold = "No"
   colHeaders = "Yes" colHeaderAlign = "LEFT"
   colHeaderItalic = "No" colHeaderBold = "No"
   selectColor = "Red" selectMode = "EDIT" pictureBar = "No"
   insertButton = "To insert" deleteButton = "To delete"
   sortAscendingButton = "Sort ASC" sortDescendingButton = "Sort DESC">
   <cfgridcolumn name = "Course_ID" dataAlign = "LEFT"
      bold = "No" italic = "No" select = "No" display = "No"
      headerBold = "No" headerItalic = "No">
   <cfgridcolumn name = "Dept_ID" header = "Department"
      headerAlign = "LEFT" dataAlign = "LEFT"
      bold = "Yes" italic = "No" select = "Yes" display = "Yes"
      headerBold = "No" headerItalic = "Yes">
   <cfgridcolumn name = "CorNumber" header = "Course ##"
      headerAlign = "LEFT" dataAlign = "LEFT"
      bold = "No" italic = "No" select = "Yes" display = "Yes"
      headerBold = "No" headerItalic = "No">
   <cfgridcolumn name = "CorName" header = "Name"
      headerAlign = "LEFT" dataAlign = "LEFT" font = "Times" bold = "No"
      italic = "No" select = "Yes" display = "Yes" headerBold = "No"
      headerItalic = "No">
   <cfgridcolumn name = "CorLevel" header = "Level"
      headerAlign = "LEFT" dataAlign = "LEFT"
      bold = "No" italic = "No" select = "Yes" display = "Yes"
      headerBold = "No" headerItalic = "No">
   <cfgridcolumn name = "CorDesc" header = "Description"
      headerAlign = "LEFT" dataAlign = "LEFT"
      bold = "No" italic = "No" select = "Yes" display = "Yes"
      headerBold = "No" headerItalic = "No">
</cfgrid>
</cfform>
</body>
</html>
...


cfgridcolumn

Description

Used with the cfgrid tag in a cfform. Use this tag to specify column data in a cfgrid control. The font and alignment attributes used in cfgridcolumn override global font or alignment settings defined in cfgrid.

Category

Forms tags

Syntax

<cfgridcolumn
   name = "column_name"
   header = "header"
   width = "column_width"
   font = "column_font"
   fontSize = "size"
   italic = "Yes" or "No"
   bold = "Yes" or "No"
   textColor = "web color" or "expression"
   bgColor = "web color" or "expression"
   href = "URL"
   hrefKey = "column_name"
   target = "URL_target"
   select = "Yes" or "No"
   display = "Yes" or "No"
   type = "type"
   headerFont = "font_name"
   headerFontSize = "size"
   headerItalic = "Yes" or "No"
   headerBold = "Yes" or "No"
   headerTextColor = "web color"
   dataAlign = "position"
   headerAlign = "position"
   numberFormat = "format"
   values = "Comma separated strings and/or numeric range"
   valuesDisplay = "Comma separated strings and/or numeric range"
   valuesDelimiter = "delimiter character">

See also

cfapplet , cfform , cfgrid tags, cfinput , cfselect , cfslider , cftextinput , cftree

History

New in ColdFusion MX: if select = "no", a user cannot select and edit the cell data, regardless of the cfgrid selectmode attribute value. When clicked, the cell border (and, depending on the selectColor value, the cell background) changes color, but the cell data cannot be edited.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of grid column element. If grid uses a query, column name must specify name of a query column.
header
Optional
Yes
Column header text. Used only if cfgrid colHeaders = "Yes".
width
Optional; see description
Column head width
Column width, in pixels.
font
Optional
As specified by cfgrid
Font of data in column.
fontSize
Optional
As specified by cfgrid
Size of text in column.
italic
Optional
As specified by cfgrid
  • Yes: displays grid control text in italics
  • No
bold
Optional
As specified by cfgrid
  • Yes: displays grid control text in bold
  • No
textColor
Optional
Color of grid element text in column, or an expression to manipulate color; hex or text.
To enter hex value, use the form "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
You can enter an expression; for example:
textColor= "(C2 LT 0 ? red : pink)"
This means: If value in Column 2 is less than 0, display value in red; otherwise, display value in pink.
See Using expressions in textColor and bgColor attributes.
  • Any color, in hex format
  • Black
  • Red
  • Blue
  • Magenta
  • Cyan
  • Orange
  • Darkgray
  • Pink
  • Gray
  • White
  • Lightgray
  • Yellow
bgColor
Optional
Color of background of grid column, or an expression to manipulate color.
See Using expressions in textColor and bgColor attributes.
  • Options: same as for textColor attribute
href
Optional
URL o r query column name that contains a URL to hyperlink each grid column with.
hrefKey
Optional
The query column to use for the value appended to the href URL of each column, instead of the column’s value.
target
Optional
Frame in which to open link specified in href.
select
Optional
  • Yes: user can select the column in grid control.
  • No: user cannot edit column, regardless of cfgrid insert and delete values. If cfgrid selectMode = "Row" or "Browse", this value is ignored.
display
Optional
Yes
  • Yes
  • No: hides column
type
Optional
  • image: grid displays image that corresponds to value in column (a built-in ColdFusion image name, or an image in cfide\classes directory or subdirectory referenced with relative URL). If image is larger than column cell, it is clipped to fit. Built-in image names are as follows:
    • - cd
    - computer
    - document
    - element
    - folder
    - floppy
    - fixed
    - remote
  • numeric: user can sort grid data numerically
  • boolean: column displays as checkbox; if cell is editable, user can change checkmark
  • string_noCase: user can sort grid data as case-insensitive text
headerFont
Optional
as specified by cfgrid
Column header font
headerFontSize
Optional
as specified by cfgrid
Column header text size, in pixels
headerItalic
Optional
as specified by cfgrid
  • Yes: displays column header in italics
  • No
headerBold
Optional
as specified by cfgrid
  • Yes: displays header in bold
  • No
headerTextColor
Optional
Color of grid control column header text.
  • Options: same as for textColor attribute
dataAlign
Optional
as specified by cfgrid
Column data alignment:
  • Left
  • Right
  • Center
headerAlign
Optional
as specified by cfgrid
Column header text alignment:
  • Left
  • Right
  • Center
numberFormat
Optional
Format for displaying numeric data in grid. See numberFormat mask characters.
values
Optional
Formats cells in column as drop-down list boxes; specify items in drop-down list. Example:
values = "arthur, scott, charles, 1-20, mabel"
valuesDisplay
Optional
Maps elements in values attribute to string to display in drop-down list. Delimited strings and/or numeric range(s).
valuesDelimiter
Optional
, [comma]
Delimiter in values and valuesDisplay attributes.


Using expressions in textColor and bgColor attributes

The textColor and bgColor attributes accept the following kinds of values:

  • A color value literal
  • A hex value
  • An expression that selects a text color based on the evaluation of a boolean expression

The syntax for an expression is as follows:

(CX operator string ? true_condition : false_condition)

The symbol meanings are as follows:

  • CX: the column that contains the value to test. For the current column, use CX; if n is the column to evaluate, use C n; for example, C2
  • operator: One of these operators: EQ (equal), GT (greater than), LT (less than)
  • string: Value to compare against. A literal, such as (C2 EQ Johnson ? blue : green); or numeric: (C2 LT 0 ? red : black)
  • true_condition: Value for textColor if condition evaluates to "true"
  • false_condition: Value for textColor if condition evaluates to "false"

If the string in the expression can be interpreted as a number, the comparisons in the expression are interpreted as numeric. Otherwise, the comparison is a string comparison.

This code shows an expression that displays the grid element in blue if the grid element contains the string "Pam"; or black, otherwise:

<cfgridcolumn name = "FirstName" textColor = "(CX EQ Pam ? blue : black)">

This example displays the text in red if the value in column 1 is greater than four; or black, otherwise:

<cfgridcolumn name = "FirstName" textColor = "(C1 GT 4 ? blue : black)">


numberFormat mask characters

You can use the following numberFormat attribute mask characters, which correspond to those in the NumberFormat function, to format output in U.S. numeric and currency styles. For more information, see NumberFormat. (This tag does not support international number formatting.)

Character | Meaning
_ | (Underscore) Digit placeholder.
9 | Digit placeholder.
. | (Period) Location of mandatory decimal point.
0 | Located to left or right of mandatory decimal point; pads with zeros.
( ) | Puts parentheses around mask if number is less than 0.
+ | Puts plus sign before positive numbers, minus sign before negative numbers.
- | Puts space before positive numbers, minus sign before negative numbers.
, | (Comma) Separates every third decimal-place with a comma.
L,C | Left-justilfy or center-justify number within width of mask column. First character of mask must be L or C. Default: right-justified.
$ | Puts dollar sign before formatted number. Must be the first character of mask.
^ | (Caret) Separates left from right formatting.

Example

For a code example, see cfgrid.


cfgridrow

Description

Lets you define a cfgrid that does not use a query as source for row data. If a query attribute is specified in cfgrid, the cfgridrow tags are ignored.

Category

Forms tags

Syntax

<cfgridrow
   data = "col1, col2, ...">

See also

cfapplet , cfform , cfgrid tags, cfinput , cfselect , cfslider , cftextinput , cftree

Attributes

Attribute | Req/Opt | Default | Description
data | Required |  | Delimited list of column values. If a value contains a comma, it must be escaped with another comma.

Usage

The following code shows how to populate a grid from a list with the cfgridrow tag:

<cfset MyList1 = "Rome,Athens,Perth,Brasilia">
<cfset MyList2 = "Italy,Greece,Australia,Brazil">
<cfform
   name = "someform" action = "cfform.cfm">
<cfgrid name="GeoGrid"  autowidth = "yes" vspace = "4"
height = "120" font="tahoma" gridlines="yes"
rowheaders="yes" rowheaderalign="left" colheaders="yes" >

   <cfgridcolumn NAME="City" header="City">
   <cfgridcolumn NAME="Country" header="Country">

   <cfloop index="Counter" from="1" to="#ListLen(MyList1)#">
      <cfgridrow data =
"#ListGetAt(MyList1,Counter)#,#ListGetAt(MyList2,(Counter))#">
   </cfloop>
</cfgrid>
</cfform>

Example

For a code example, see cfgrid.

The following example populates two grids from the results of a query, as follows:

  • One uses cfgridrow within the cfquery tag, using the query to generate rows
  • One uses cfgridrow outside the cfquery tag, using a cfloop tag to generate rows.
<!--- This example shows cfgrid, cfgridcolumn, cfgridrow, cfgridupdate tags --->
<!--- If the gridEntered form field has been tripped, perform the gridupdate
on the table specified in the database. Using the default value
keyonly=yes lets us change only the information that differs from
the previous grid --->
<cfif isdefined("form.gridentered") is true>
<cfgridupdate grid="FirstGrid" datasource="cfsnippets"
   tablename="CourseList"  keyonly="Yes">
</cfif>

<!--- query the database to fill up the grid --->
<cfquery name="GetCourses" datasource="cfsnippets">
   select   Course_ID, Dept_ID, CorNumber, CorName, CorLevel, CorDesc
   FROM     CourseList
   ORDER by Dept_ID ASC, CorNumber ASC
</cfquery>
<html>
<head>
<title>cfgridrow example</title>
</head>
<body>
<h3>cfgridrow Example</h3>
<I>Try adding a course to the database, and then deleting it.</I>
<!--- call the cfform to allow us to use cfgrid controls --->
<cfform action="cfgridrow.cfm">

<!--- When inserting rows while running under UNIX, you must also specify
a value for Course_ID --->
<!--- cfgridcolumn tags are used to change the parameters involved in
displaying each data field in the table--->

<cfgrid name="FirstGrid" width="600" query="GetCourses" insert="yes"
   delete="yes" sort="yes" font="tahoma" bold="no" italic="no"
   appendkey="no" highlighthref="no" griddataalign="left" gridlines="yes"
   rowheaders="yes" rowheaderalign="left" rowheaderitalic="no"
   rowheaderbold="no" colheaders="yes" colheaderalign="left"
   colheaderitalic="no" colheaderbold="no" selectcolor="red"
   selectmode="edit" picturebar="no" insertbutton="to insert"
   deletebutton="to delete" sortascendingbutton="sort asc"
   sortdescendingbutton="sort desc">
   <cfgridcolumn name="Dept_ID" header="Department" headeralign="left"
dataalign="left" bold="yes" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="yes">
   <cfgridcolumn name="CorNumber" header="Course ##" headeralign="left"
dataalign="left" bold="no" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorName" header="Name" headeralign="left"
dataalign="left" font="times" bold="no" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorLevel" header="Level" headeralign="left"
dataalign="left" bold="no" italic="no" select="yes" display="yes"
headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorDesc" header="Description" headeralign="left"
dataalign="left" bold="no" italic="no" select="yes" display="yes"
headerbold="no" headeritalic="no">
   <cfgridcolumn name="Course_ID" header="Course ID (Do Not Specify on NT)"
dataalign="left" bold="no" italic="no" select="yes" display="yes"
headerbold="no" headeritalic="no">
</cfgrid>

<!--- send the grid back to this page, where we  determine whether anything has
changed, and thus whether to run the cfgridupdate --->
<input type="Submit" name="submit" value="Apply Changes">
<input type="hidden" name="gridEntered" value="yes">

<h3>Example Two</h3>
<p>This grid shows how the same grid can be built using cfgridrow with cfloop
(i.e., defining query external to cfgrid, rather than within cfgrid).</p>
<!--- cfgridcolumn is used to define  container columns.
     cfgridrow is used to define the data put into those containers --->
<cfgrid name="SecondGrid" width=600 insert="no"
   delete="no" sort="yes" bold="no" italic="no"
   appendkey="no" highlighthref="no" griddataalign="left" gridlines="yes"
   rowheaders="no" rowheaderalign="left" rowheaderitalic="no"
   rowheaderbold="no" colheaders="yes" colheaderalign="left"
   colheaderitalic="no" colheaderbold="no" selectmode="browse"
   picturebar="yes">
   <cfgridcolumn name="Course_ID" dataalign="left" bold="no" italic="no"
select="no" display="no" headerbold="no" headeritalic="no">
   <cfgridcolumn name="Dept_ID" header="Department" headeralign="left"
dataalign="left" bold="yes" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="yes">
   <cfgridcolumn name="CorNumber" header="Course ##" headeralign="left"
dataalign="left" bold="no" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorName" header="Name" headeralign="left"
dataalign="left" font="times" bold="no" italic="no"
select="yes" display="yes" headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorLevel" header="level" headeralign="left"
dataalign="left" bold="no" italic="no" select="yes"
display="yes" headerbold="no" headeritalic="no">
   <cfgridcolumn name="CorDesc" header="Description" headeralign="LEFT"
dataalign="left" bold="no" italic="no" select="yes" display="yes"
headerbold="no" headeritalic="no">
<!--- use cfloop, loop through query, define cfgridrow data each time through --->
   <cfloop query="GetCourses">
      <cfgridrow data="#Course_ID#,#Dept_ID#,#CorNumber#,#CorName#,
#CorLevel#,#CorDesc#">
   </cfloop>
</cfgrid>
</cfform>
</body>
</html>


cfgridupdate

Description

Used within a cfgrid tag. Updates data sources directly from edited grid data. This tag provides a direct interface with your data source.

This tag applies delete row actions first, then insert row actions, then update row actions. If it encounters an error, it stops processing rows.

Category

Forms tags

Syntax

<cfgridupdate
   grid = "gridname"
   dataSource = "data source name"
   tableName = "table name"
   username = "data source username"
   password = "data source password"
   tableOwner = "table owner"
   tableQualifier = "qualifier"
   keyOnly = "Yes" or "No">

See also

cfapplet , cfform , cfgrid tags, cfinput , cfselect , cfslider , cftextinput , cftree

History

New in ColdFusion MX: The connectString, dbName, dbServer, dbtype, provider and providerDSN attributes are deprecated. Do not use them. They do not work, and might cause an error, in releases later than ColdFusion 5.

Attributes

Attribute
Req/Opt
Default
Description
grid
Required
Name of cfgrid form element that is the source for the update action.
dataSource
Required
Name of data source for the update action.
tableName
Required
Name of table to update.
For ORACLE drivers, entry must be upper-case.
For Sybase driver, entry is case-sensitive; must be same case as used when table was created
username
Optional
Overrides username value specified in ODBC setup.
password
Optional
Overrides password value specified in ODBC setup.
tableOwner
Optional
Table owner, if supported.
tableQualifier
Optional
Table qualifier, if supported. Purpose:
  • SQL Server and Oracle driver: name of database that contains table
  • Intersolv dBASE driver: directory of DBF files
keyOnly
No
Applies to the update action:
  • Yes: the WHERE criteria are limited to the key values
  • No: the WHERE criteria include key values and the original values of changed fields

Example

<!--- This example shows the cfgridupdate tag--->
...
<!--- If the gridEntered form field has been tripped, perform
the gridupdate on the table specified in the database.
Using the default value keyonly = yes lets us change only the
information that differs from the previous grid --->
<cfif IsDefined("form.gridEntered") is True>
<cfgridupdate grid = "FirstGrid" dataSource = "cfsnippets"
 tableName = "CourseList" keyOnly = "Yes">
</cfif>
...


cfheader

Description

Generates custom HTTP response headers to return to the client.

Category

Data output tags, Page processing tags

Syntax

<cfheader
   name = "header_name"
   value = "header_value">
or
<cfheader
   statusCode = "status_code"
   statusText = "status_text">

See also

cfcache , cfflush , cfhtmlhead , cfinclude , cfsetting , cfsilent

Attributes

Attribute | Req/Opt | Default | Description
name | Required if statusCode not specified |  | Header name
value | Optional |  | HTTP header value
statusCode | Required if name not specified |  | Number. HTTP status code
statusText | Optional |  | Explains status code

Usage

If you use this tag after the cfflush tag on a page, an error is thrown.

Example

<h3>cfheader Example</h3>

<p>cfheader generates custom HTTP response headers to return to the client.
<p>This example forces browser client to purge its cache of requested file.
<cfheader name = "Expires" value = "#Now()#">


cfhtmlhead

Description

Writes text to the head section of a generated HTML page. It is useful for embedding JavaScript code, or putting other HTML tags, such as meta, link, title, or base in an HTML page header.

Category

Page processing tags

Syntax

<cfhtmlhead
   text = "text">

See also

cfcache , cfflush , cfheader , cfheader , cfinclude , cfsetting , cfsilent

Attributes

Attribute | Req/Opt | Default | Description
text | Required |  | Text to add to the <head> area of an HTML page.

Usage

If you use this tag after the cfflush tag on a page, an error is thrown.

Example

<body>
<!--- This example shows the use of cfhtmlhead --->
<cfhtmlhead
   text="<meta name=""Description""
   content=""This is an example of a generated header"">">

<p>cfhtmlhead writes the text specified in the text attribute to the
&lt;HEAD&gt;section of a generated HTML page. cfhtmlhead can be
useful for embedding JavaScript code, or placing other HTML tags
such as META, LINK, TITLE, or BASE in an HTML header.
<p>View the source of this frame to see that the title of the page is
generated by the cfhtmlhead tag.
</body>


cfhttp

Description

Executes HTTP POST and GET operations on files. You can execute standard GET operations and create a query object from a text file. POST operations upload MIME file types to a server, or post cookie, formfield, URL, file, or CGI variables directly to a server.

Category

Forms tags, Internet Protocol tags

Syntax

<cfhttp
   url = "hostname"
   port = "port_number"
   method = "get_or_post"
   username = "username"
   password = "password"
   name = "queryname"
   columns = "query_columns"
   firstrowasheaders = "yes" or "no"
   path = "path"
   file = "filename"
   delimiter = "character"
   textQualifier = "character"
   resolveURL = "yes" or "no"
   proxyServer = "hostname"
   proxyPort = "port_number"
   userAgent = "user_agent"
   throwOnError = "yes" or "no"
   redirect = "yes" or "no"
   timeout = "timeout_period"
   charset = "character set">
</cfhttp>

See also

cfftp , cfhttpparam , cfldap , cfmail , cfmailparam , cfpop

History

New in ColdFusion MX:

  • The firstrowasheaders attribute is new.
  • The charset attribute is new.
  • ColdFusion uses the Sun JSSE library, which supports 128-bit encryption, to support Secure Sockets Layer (SSL).

Attributes

Attribute
Req/Opt
Default
Description
url
Required
http
Absolute URL of host name or IP address of server on which file resides. URL must include protocol (http or https) and hostname. It can contain a port number. This value overrides port value.
port
Optional
80
Port number on server from which object is requested. When used with resolveURL, URLs of retrieved documents that specify a port number are automatically resolved, so that links in retrieved document remain functional. Value in url attribute overrides this value.
method
Optional
get
  • get: downloads text or binary file, or create query from the contents of a text file.
  • post: sends information to server page or CGI program for processing. Requires a cfhttpparam tag.
username
Optional
A username. May be required by server.
password
Optional
A password. May be required by server
name
Optional
Name to assign to a query if it is constructed from returned HTTP results.
columns
Optional
Column names for a query, when creating it as a result of a cfhttp method = "get".
By default, the first row of a text file is interpreted as column heads. If there are column heads in the text file from which the query is drawn, do not specify this attribute, except to overwrite them.
If a duplicate column heading is encountered, ColdFusion appends an underscore to the name to make it unique.
If there are no column headers in the text file, or to override those in the file, specify the columns attribute. ColdFusion never processes the first row of a file as data,.
firstrowasheaders
Optional
yes
Determines how ColdFusion processes the first row of the query record set:
  • yes:
    • - If the columns attribute is not specified: processes as column heads
    - If the columns attribute is specified: this attribute is not used
  • no:
    • - If the columns attribute is not specified: processes as data, and generates column names; for example, "column_1"
    - If the columns attribute is specified: this attribute is not used
path
Optional
Path to directory in which to store file. If path is not specified in POST or GET, a variable (cfhttp.fileContent) is created; you can use it to display the post results, in a cfoutput tag.
file
Required if post and if path is specified
Name of file that is accessed. For a get operation, defaults to name specified in url. Enter path information in the path attribute.
delimiter
Required to create query
, [comma]
  • tab
  • comma
textQualifier
Required to create query
"" [double quotation mark]
Start and end of a column. If it is embedded in column, this value must be escaped. For example, if qualifier is a double quotation mark, it is escaped as """". If there is no text qualifier in the file, specify " ".
resolveURL
Optional
No
Applies to get and post.
  • Yes: internal URLs in a page reference returned into fileContent internal variable are fully resolved, including port number, so that links in the page remain functional. Applies to these HTML tags:
    • - img src
    - a href
    - form action
    - applet code
    - script src
    - embed src
    - embed pluginspace
    - body background
    - frame src
    - bgsound src
    - object data
    - object classid
    - object codebase
    - object usemap
proxyServer
Optional
Host name or IP address of a proxy server.
proxyPort
Optional
80
Port number on proxy server from which object is requested. When used with resolveURL, the URLs of retrieved documents that specify a port number are automatically resolved, so that links in the retrieved document remain functional.
userAgent
Optional
User agent request header.
throwOnError
Optional
No
  • Yes: throw an exception that can be caught with the cftry and cfcatch tags
  • No
redirect
Optional
Yes
If No, and throwOnError = "yes": if cfhttp fails, execution stops, and the status code and associated error message are returned in the variable cfhttp.statuscode.
To determine where execution would be redirected, use the variable cfhttp.responseHeader[LOCATION]. The key LOCATION shows the redirection path. ColdFusion follows a maximum of four redirects on a request. If there are more, ColdFusion functions as if redirect = "no".
  • Yes: redirect execution
  • No: stop execution
timeout
Optional
Value, in seconds. When a URL timeout is specified in the browser, this setting takes precedence over the ColdFusion Administrator timeout, and ColdFusion uses the lesser of the URL timeout and the timeout passed in the timeout attribute, so that the request always times out before, or at the same time as, the page.
If URL timeout is not specified, ColdFusion uses the lesser of the Administrator timeout and the timeout passed in the timeout attribute.
If the timeout is not set in any of these, ColdFusion waits indefinitely for the cfhttp request to process.
This attribute does not function with JDK 1.3.
charset
Optional
The server charset; if none, UTF-8
A Java character set name for the file or url in a GET or POST. The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Usage

If this value includes the substring "https" (which indicates that the object of the request is a secure server) but does not include a port number, the default value of the port attribute is 443. (If the URL value includes a port number, its value overrides the value of port.)

For the ColdFusion Administrator timeout and the URL timeout to take effect, you must enable the timeout in the ColdFusion Administrator, Server Settings page. For more information, see Administering ColdFusion MX.


Variables returned by a cfhttp get operation

The cfhttp tag returns data in variables. For example, if you specify a URL that points to a text or binary file in a cfhttp method = "get" operation, the file is downloaded and stored in a ColdFusion variable or file.

  • The fileContent variable is available for text and MIME file types.
  • The mimeType variable is available for all file manipulations.
  • The Header and responseHeader variables display response headers.

These variables can be accessed in this way:

#cfhttp.fileContent#
#cfhttp.mimeType#
#cfhttp.header#
#cfhttp.responseHeader[http_header_key]#

The responseHeader variable is returned as a CFML structure; the others, as strings.


Building a query from a delimited text file

To download a file in a ColdFusion page so that a query can be built using the file, the file must be either comma- or tab-delimited. Macromedia recommends that you include text qualification. The file is parsed and an appropriate query is built from it. You can specify columns in the attribute list so the client can override the columns specified in the file.

There is error checking within the tag that prevents a user from entering an invalid column name, or using an invalid column name that was specified in the original file. If an illegal filename is encountered, the illegal characters are stripped. This action could produce duplicate column names, so duplicate columns are renamed and inserted into the query header.

The query has all of the functionality of a standard cfquery object, as follows:

  • HTTP POST: You can nest cfhttpparam tags within a cfhttp tag. The browser can be pointed to a URL that specifies a CGI executable or a ColdFusion page. Because cfhttpparam tags can be nested, you can construct a multipart/form-data style post. A file content variable is created; you can use it in a cfoutput tag. If path and file attributes are specified, the data returned from the server is saved to the specified location.
  • Authentication: cfhttp supports Windows NT Basic Authentication for GET and POST operations. However, Basic Authentication does not work if your web server has Windows NT Challenge/Response (Microsoft IIS) enabled.
  • Encryption: cfhttp uses SSL to negotiate secure transactions.
  • cfhttp.statuscode: cfhttp provides the cfhttp.statuscode variable for access to the HTTP error string associated with the error if the throwOnError attribute is set to No (or if it is not specified, because it defaults to No).

The cfhttp tag returns the following variables:

Name
Description
#cfhttp.fileContent#
File contents, for text and MIME files.
#cfhttp.mimeType#
MIME type.
#cfhttp.responseHeader[http_hd_key]#
Response headers. If there is one instance of a header key, value can be accessed as simple type. If there is more than one instance, values are put in an array in responseHeader structure.
#cfhttp.header#
Raw response header.
#cfhttp.statuscode#
HTTP error code and associated error string, if throwOnError = "no".

Terminate a cfhttp method = "post" operation with </cfhttp>.

Example

<!--- This example shows the use of CFHTTP to pull information dynamically from
the snippets directory --->
<p>This view-only example shows the ability of CFHTTP to pull the contents of
a web resource from the Internet or from a local directory.
<!---
<form action="index.cfm" method="POST">
Try entering a URL for the tag to return:
   <input type="Text" size="25" name="urladdress"
      value="http://www.macromedia.com">
   <input type="Submit" name="" value="get page">
</form>
<!----- sets a default value for a URL to retrieve ----->
<cfparam name="urladdress"
   default="http://localhost/cfdocs/index.htm">
<!--- if we have passed a url address in the form, display the address --->
<cfif IsDefined("form.urladdress") is True>
   <!--- do simple error check to avoid crashing the tag --->
   <cfif Trim(Form.urladdress) is ""
      or Trim(Form.urladdress) is "http://">
      <!--- if error condition tripped, set alternative --->
      <cfset urlAddress ="http://localhost/cfdocs/index.htm">
      <h4>because you entered no url or an empty string, the tag will
      return the following address: http://localhost/cfdocs/index.htm</h4>
   <cfelse>
      <!--- otherwise use address passed from form --->
      <cfset urlAddress = form.urladdress>
   </cfif>
   <!--- use CFHTTP tag to get the file content represented       by urladdress --->
   <cfhttp url="#urladdress#"
      method="GET" resolveurl="YES">
   </cfhttp>
<cfelse>
   <!---    the first time through, retrieve a URL that we know exists ---->
   <cfhttp url="http://localhost/cfdocs/index.htm"
      method="GET" resolveurl="YES">
   </cfhttp>
</cfif>
<!----    Now, output the file, including the mimetype and content ------>
<h3>Show the file</h3>
<cfoutput>
   <p>Your file was of type: #CFHTTP.MimeType#
   <p>#HTMLCodeFormat(CFHTTP.FileContent)#
</cfoutput> --->


cfhttpparam

Description

Required for a cfhttp POST operation. Specifies parameters to build the operation.

Category

Forms tags, Internet Protocol tags

Syntax

<cfhttpparam
   name = "name"
   type = "type"
   value = "transaction type"
   file = "filename">

See also

cfftp , cfhttp , cfldap , cfmail , cfmailparam , cfpop

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Variable name for data that is passed
type
Required
Transaction type:
  • URL
  • FormField
  • Cookie
  • CGI
  • File
value
Optional if type = "File"
Value of URL, FormField, Cookie, File, or CGI variables that are passed.
file
Required if type = "File"
File name

Usage

This tag’s parameter values are URL-encoded, so the values of special characters (such as the ampersand) are preserved when they are passed to the server. For more information, see the function URLEncodedFormat.

Example

<p>This view-only example shows the use of cfhttpparam to show the values
of passed variables on another HTML reference, accessed by cfhttp.
The other file could output the value of form.formtest, url.url_test,
cgi.cgi_test, and cookie.cookie_test to prove that this page is working:

<h3>Sample Other File Listing</h3>
<cfoutput>#HTMLCodeFormat("

<html>
<head>
<title>Sample Page</title>
</head>

<body>
<h3>Output the passed variables</h3>
<cfoutput>
   Form variable: ##form.form_test##
   <br>URL variable: ##URL.url_test##
   <br>Cookie variable: ##Cookie.cookie_test##
   <br>CGI variable: ##CGI.cgi_test##
</cfoutput>
</body>
</html>

")#</cfoutput>

<!--- <p>
<cfhttp
      method = "post" url = "http://localhost/someotherfile.cfm">
   <cfhttpparam
      name = "form_test" type = "FormField" value = "This is a form variable">
   <cfhttpparam
      name = "url_test" type = "URL" value = "This is a URL variable">
   <cfhttpparam
      name = "cgi_test" type = "CGI" value = "This is a CGI variable">
   <cfhttpparam
      name = "cookie_test" type = "Cookie" value = "This is a cookie">
</cfhttp>

<cfoutput>
    #cfhttp.fileContent#
</cfoutput> --->


cfif

Description

Creates simple and compound conditional statements in CFML. Tests an expression, variable, function return value, or string. Used, optionally, with the cfelse and cfelseif tags, which are also described in this section.

Category

Flow-control tags

Syntax

<cfif expression>
   HTML and CFML tags
<cfelseif expression>
   HTML and CFML tags
<cfelse>
   HTML and CFML tags
</cfif>

See also

cfabort , cfbreak , cfexecute , cfexit , cflocation , cfloop , cfswitch , cfthrow , cftry

Usage

When testing the return value of a function that returns a Boolean, you do not have to define the True condition explicitly. This example uses the IsArray function:

<cfif IsArray(myarray)>

If successful, IsArray evaluates to Yes, the string equivalent of the Boolean True. This is preferred over explicitly defining the True condition this way:

<cfif IsArray(myarray) IS True>

For example:

<cfif "11/23/1998 " GT "11/15/1998">

This switch is set on the ColdFusion Administrator Server Settings page. For more information, see Administering ColdFusion MX.

This tag requires an end tag.

Example

In this example, variables are shown within pound signs. This is not required.

<!--- This example shows the interaction of cfif, cfelse, and cfelseif --->
<!----- first, perform a query to get some data ----->
<cfquery name="getCenters" datasource="cfsnippets">
   SELECT Center_ID, Name, Address1, Address2, City, State, Country,
      PostalCode, Phone, Contact
   FROM Centers
   ORDER by City, State, Name
</cfquery>
<p>CFIF gives us the ability to perform conditional logic based on a condition
or set of conditions.
<p>For example, we can output the list of Centers from the snippets datasource
by group and only display them <b>IF</b> City = San Diego.
<hr>
<!---- use CFIF to test a condition when outputting a query ----->
<p>The following centers are in San Diego:
<cfoutput query="getCenters">
      <cfif Trim(City) is "San Diego">
         <br><b>Name/Address:</b>#Name#, #Address1#, #City#, #State#
         <br><b>Contact:</b> #Contact#
         <br>
      </cfif>
</cfoutput>
<hr>
<p>If we would like more than one condition to be the case, we can ask for
a list of the centers in San Diego <b>OR</b> Santa Ana. If the center
does not follow this condition, we can use CFELSE to show only
the names and cities of the other centers.
<p>Notice how a nested CFIF is used to specify the location of
the featured site (Santa Ana or San Diego).
<!----- use CFIF to specify a conditional choice for multiple options;
also note the nested CFIF --->
<p>Complete information is shown for centers in San Diego or Santa Ana.
All other centers are listed in italics:
<cfoutput query="getCenters">
   <cfif Trim(City) is "San Diego" OR Trim(City) is "Santa Ana">
      <h4>Featured Center in
         <cfif Trim(City) is "San Diego">
            San Diego
         <cfelse>
            Santa Ana
         </cfif>
         </h4> <b>Name/Address:</b>#Name#, #Address1#, #City#, #State#
         <br><b>Contact:</b> #Contact#<br>
   <cfelse>
      <br><i>#Name#, #City#</i>
   </cfif>
</cfoutput>
<hr>
<p>Finally, we can use CFELSEIF to cycle through a number of conditions and
produce varying output. Note that you can use CFCASE and CFSWITCH for a more
elegant representation of this behavior.
<p> <!------- use CFIF in conjunction with CFELSEIF to specify more than one
branch in a conditional situation --->
<cfoutput query="getCenters">
   <cfif Trim(City) is "San Diego" OR Trim(City) is "Santa Ana">
      <br><i>#Name#, #City#</i> (this one is in
            <cfif Trim(City) is "San Diego">San Diego
            <cfelse>Santa Ana
            </cfif>)
         <cfelseif Trim(City) is "San Francisco">
            <br><i>#Name#, #City#</i> (this one is in San Francisco)
         <cfelseif Trim(City) is "Suisun">
            <br><i>#Name#, #City#</i> (this one is in Suisun)
         <cfelse> <br><i>#Name#</i>
            <b>Not in a city we track</b>
         </cfif>
</cfoutput>


cfimpersonate

Description

This tag is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML.

History

New in ColdFusion MX: this tag is obsolete. It does not work in ColdFusion MX and later releases.


cfimport

Description

You can use the cfimport tag to import custom tags from a directory as a tag library, or to import a Java Server Page (JSP) tag library. A JSP tag library is a packaged set of tag handlers that conform to the JSP 1.1 tag extension API.

Category

Application framework tags

Syntax

<cfimport
   taglib = "taglib-location"
   prefix = "custom"
   webservice = "URL">

See also

cfapplication

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute
Req/Opt
Default
Description
taglib
Required
Tag library URI:
  • A directory in which customer tags are stored
  • A URL path to a JAR in a web-application; for example, "/WEB-INF/lib/sometags.jar"
  • A path to a tag library descriptor; for example,
    "/sometags.tld"
prefix
Prefix by which to access imported JSP tags on a CFML page.
To import tags directly, specify an empty value, "". Use this to create server-side versions of common HTML tags.
webservice
Optional
URL of a WSDL file.

Usage

The following example imports the tags from the directory myCustomTags:

<cfimport
   prefix="mytags"
   taglib="myCustomTags">

You can import multiple tag libraries using one prefix. If there are duplicate tags in a library, the first one takes precedence.

JSP tags have fixed attributes; however, if the tag supports runtime attribute expressions, most tag libraries support the use of the syntax #expressions#.

To reference a JSP tag in a CFML page, use the syntax <prefix:tagname>. Set the prefix value in the prefix attribute.

To use JSP custom tags in a ColdFusion page, follow these steps:

  1. Put a JSP tag library JAR file (for example, myjsptags.jar) into the ColdFusion server directory wwwroot/WEB-INF/lib.
  2. At the top of a CFML page, insert code such as the following:
   <cfimport
      prefix="mytags"
      taglib="/WEB-INF/lib/myjsptags.jar">

To reference a JSP tag from a JAR file, use the following syntax:

<cfoutput>
   <mytags:helloTag message="#mymessage#" />
<cfoutput>

The cfimport tag does not work within a cfinclude call. ColdFusion does not throw an error in this situation. To include tags from a JSP tag library, you must put the cfimport tag at the top of every page that is called by the cfinclude tag. (Putting the cfimport tag into an application.cfm file does not propagate the import.) For example, put a statement such as the following in each page that is called by the cfinclude tag:

<cfimport taglib="/WEB-INF/webcomponent" prefix="c">

You cannot use this tag to suppress output from a tag library.

For more information, see the Java Server Page 1.1 specification.

Example

<h3>cfimport example - view only</h3>
<cftry>
   <!--- Import the JRun Custom Tag Libraries --->
   <cfimport
taglib="jruntags.jar"
prefix="customtag">

   <customtag:sql datasrc="#regdatasource#" id="x">
      SELECT employee_id, firstname, lastname, email, phone, department
      FROM employees
      WHERE employee_id < 3
   </customtag:sql>

   <customtag:param id="x" type="allaire.taglib.querytable"/>
   <table>
      <customtag:foreach group="#x#">
      <tr>
         <cfoutput>
            <TD>#x.get("employee_id")#</TD>
            <TD>#x.get("firstname")#</TD>
            <TD>#x.get("lastname")#</TD>
            <TD>#x.get("email")#</TD>
            <TD>#x.get("phone")#</TD>
            <TD>#x.get("department")#</TD>
         </cfoutput>
      </tr>

      </customtag:foreach>
   </table>
   <cfcatch>
      <cfoutput>#CFCATCH.message# - #CFCATCH.DETAIL# </cfoutput>
   </cfcatch>
</cftry>

<h3>id= cfimport-jruntags-sql-pos-1-t1</h3>
<table>
   <tr>
      <td>1</td>
      <td>carolynn</td>
      <td>peterson</td>
      <td>cpeterson</td>
      <td>(612) 832-7654</td>
      <td>sales</td>
   </tr>
   <tr>
      <td>2</td>
      <td>dave</td>
      <td> heartsdale</td>
      <td>fheartsdale</td>
      <td>(612) 832-7201</td>
      <td>accounting</td>
   </tr>
</table>


cfinclude

Description

Embeds references to ColdFusion pages in CFML. You can embed cfinclude tags recursively. For another way to encapsulate CFML, see cfmodule. (A ColdFusion page was formerly sometimes called a ColdFusion template or a template.)

Category

Flow-control tags, Page processing tags

Syntax

<cfinclude
   template = "template_name">

See also

cfcache , cfflush , cfheader , cfhtmlhead , cfsetting , cfsilent

History

New in ColdFusion MX: If you use this tag to include a CFML page whose length is zero bytes, an empty page displays. (In earlier releases, an error message displays.)

Attributes

Attribute | Req/Opt | Default | Description
template | Required |  | A logical path to a ColdFusion page.

Usage

ColdFusion searches for included files in the following sequence:

  1. In the directory of the current page
  2. In directories mapped in the ColdFusion Administrator for the included file

Example

<!--- This example shows the use of cfinclude to paste CFML
or HTML code into another page dynamically --->

<h4>This example includes the main.htm page from the CFDOCS directory.
The images do not display, because they are located in
a separate directory. However, the page appears fully rendered
within the contents of this page.</h4>
<cfinclude template = "/cfdocs/main.htm">


cfindex

Description

Populates a Verity search engine collection with an index of documents on a file system or of ColdFusion query result sets.

A collection must exist before it can be populated.

A collection can be indexed in the following ways:

  • In ColdFusion, with the cfindex tag
  • In the ColdFusion Administrator, which calls the cfindex tag
  • Using a native Verity indexing tool, such as Vspider or MKVDK

For more information, see Developing ColdFusion MX Applications with CFML.

Category

Extensibility tags

Syntax

<cfindex
   collection = "collection_name"
   action = "action"
   type = "type"
   title = "title"
   key = "ID"
   body = "body"
   custom1 = "custom_value"
   custom2 = "custom_value"
   URLpath = "URL"
   extensions = "file_extensions"
   query = "query_name"
   recurse = "Yes" or "No"
   language = "language">

See also

cfcollection , cfexecute , cfobject , cfreport , cfsearch , cfwddx

History

New in ColdFusion MX:

  • The action attribute value optimize is obsolete. It does not work, and might cause an error, in ColdFusion MX.
  • It is not necessary to specify the external attribute. (ColdFusion automatically detects whether a collection is internal or external.)
  • ColdFusion supports Verity operations on Acrobat PDF files.
  • This tag can throw the SEARCHENGINE exception.
  • This tag accepts collection names that include spaces.

Attributes

Attribute
Req/Opt
Default
Description
collection
Required
  • Name of a collection that is registered by ColdFusion; for example, "personnel"
  • Name and absolute path of a collection that is not registered by ColdFusion; for example:
    "e:\collections\personnel"
action
Depends on collection attribute value; see Usage section
  • update: updates a collection and adds key to the index. Do not use the cflock tag with this option.
  • delete: deletes data in the entities specified by the type attribute
  • purge: deletes all keys from a collection
  • refresh: purges all keys from a collection, then updates it.
type
Optional
custom, if query attribute is specified. file, otherwise.
  • file: using the key attribute value of the query result as input, applies action value to filenames or filepaths.
  • path: using the key attribute value of the query result as input, applies action to filenames or filepaths that pass the extensions filter
  • custom: If action = "update" or "delete": applies action to custom entities in query results.
title
Optional
  • Title for collection
  • Query column name for type and a valid query name
Permits searching collections by title or displaying a separate title from the key
key
Depends on action attribute value; see Usage section
(empty string)
  • Absolute path and file name, if type = "file"
  • Absolute path, if type = "path"
  • A query column name (typically, the primary key column name), if type = "custom"
  • A query column name, if type = any other value
This attribute is required for the actions listed, unless you intend for its value to be an empty string.
body
Required if type = "custom"; see Usage section
  • ASCII text to index
  • Query column name(s), if name is specified in query
You can specify columns in a delimited list. For example: "emp_name, dept_name, location"
custom1
Optional
Custom field in which you can store data during an indexing operation. Specify a query column name for type, and a query name.
custom2
Optional
Usage is the same as for custom1.
URLpath
Optional
If type="file" or "path", specifies the URL path. When the collection is searched with cfsearch, this pathname is prefixed to file names and returned as the url attribute.
extensions
Optional
HTM, HTML, CFM, CFML, DBM, DBML
Delimited list of file extensions that ColdFusion uses to index files, if type = "Path".
"*." returns files with no extension.
For example: the following code returns files with a listed extension or no extension: extensions = ".htm, .html, .cfm, .cfml, "*."
query
Required if type = "custom"; see Usage section
Query against which collection is generated
recurse
Optional
No
  • Yes: if type = "path", directories below the path specified in key are included in indexing operation
  • No
language
Optional
English
For options, see cfcollection. Requires the appropriate (European or Asian) Verity Locales language pack.

Usage

This tag populates Verity search engine collections with metadata from the following sources:

  • Documents stored on a file system
  • ColdFusion query result sets

The following table shows the dependent relationships among this tag’s attribute values:

Specifying this attribute is required, optional or unnecessary (blank): | For this action attribute value:
 | purge | delete | update or refresh
collection | Required | Required | Required
type |  | Optional | If type = "file", "path", or "custom": Optional.
title |  |  | If type = "file", "path", or "custom": Optional. Otherwise: unnecessary.
key |  | Required | If type = "file", "path", or "custom": Required. Otherwise: unnecessary.
body |  |  | If type = "custom": Required. Otherwise: unnecessary.
custom1 |  |  | If type = "file", "path", or "custom": Optional. Otherwise: unnecessary.
custom2 |  |  | If type = "file", "path", or "custom": Optional. Otherwise: unnecessary.
URLPath |  |  | If type = "file" or "path": Optional. Otherwise: unnecessary.
extensions |  |  | If type = "path": Optional. Otherwise: unnecessary.
query |  | If type = "file", "path": Optional. If type = "custom": Required. | If type = "file", "path": Optional. If type = "custom": Required.
recurse |  |  | If type = "path": Optional. Otherwise: unnecessary.
language |  | If type = "file", "path", or "custom": Optional. | If type = "file", "path", or "custom": Optional.

For all action values of this tag except update, use the cflock tag to protect the collection during tag execution.

For information on the file types you can use with the Verity search engine, see Article 22492, ColdFusion Server (versions 4.5 and higher): Supported File Types for Verity, on the Macromedia ColdFusion Support Center, at http://www.macromedia.com/support/coldfusion/.

Example

<!--- for ACTION=UPDATE ----------------------------------------------->
<!--- for ACTION=UPDATE, #1 (TYPE=FILE) (key is a filename) ---->
<cfindex
      collection="snippets"
      action="update"
      type="file"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2" >

<!--- for ACTION=UPDATE, #2 (TYPE=FILE) (key is a query result set column) ---->
<cfquery       name="bookquery"
      datasource="book">
      select *from book where bookid='file'
</cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="update"
      type="file"
      query="bookquery"
      key="description"
      urlpath="url">

<!--- for ACTION=UPDATE, #3 (TYPE=PATH) (extensions .htm, .html,.cfm,.cfml) --->
<cfindex       collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions=".htm, .html, .cfm, .cfml" >

<!--- for ACTION=UPDATE, #4 (TYPE=PATH)
      (extensions are       files with no extension) ---->
<cfindex
      collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions="*." >

<!--- for ACTION=UPDATE, #5 (TYPE=PATH)
      (extensions are files with any extension) ---->
<cfindex
      collection="snippets"
      action="update"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets"
      custom1="custom1"
      custom2="custom2"
      recurse="no"
      extensions=".*">

<!--- for ACTION=UPDATE, #6 (TYPE=PATH) (where the key
      is a query result set column) ---->
<cfquery       name="bookquery"
      datasource="book">
      select * from book where bookid='path1' or bookid='path2'
</cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="update"
      type="path"
      query="bookquery"
      key="description"
      urlpath="url" >

<!--- for ACTION=UPDATE, #7 (TYPE=CUSTOM) ---->
<cfquery       name="book"
      datasource="book">
      select * from book
</cfquery>
<cfindex
      collection="custom_book"
      action="update"
      type="custom"
      body="description"
      key="bookid"
      query="book">

<!--- for ACTION=REFRESH----------------------------------------------->
<!--- ACTION=REFRESH, #1 (TYPE=FILE) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="Refresh"
      type="file"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm"
      urlpath="http://localhost/"
      custom1="custom1"
      custom2="custom2" >
</cflock>

<!--- ACTION=REFRESH, #2 (TYPE=PATH) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="refresh"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      urlpath="http://localhost/cfdocs/snippets/"
      custom1="custom1"
      custom2="custom2"
      recurse="yes"
      extensions=".htm,.html,.cfm,.cfml" >
</cflock>

<!--- ACTION=REFRESH, #3 (TYPE=CUSTOM) ---->
<cfquery       name="book"
      datasource="book">
      select * from book
</cfquery>
<cfindex
      collection="custom_book"
      action="refresh"
      type="custom"
      body="description"
      key="bookid"
      query="book">

<!--- for ACTION=DELETE----------------------------------------------->

<!--- ACTION=DELETE, #1 (TYPE=FILE) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="delete"
      key="c:\inetpub\wwwroot\cfdocs\snippets\abs.cfm" >
</cflock>

<!--- ACTION=DELETE, #2 (TYPE=FILE) (the key is a query result set column) ---->
<cflock       name="verity"
      timeout="60">
<cfquery       name="book"
      datasource="book">
      select * from book where bookid='file'
</cfquery>
<cfoutput
      query="book">
          --#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="delete"
      type="file"
      query="book"
      key="description" >
</cflock>

<!--- ACTION=DELETE, #3 (TYPE=PATH) ---->
<cflock       name="verity"
      timeout="60">
<cfindex
      collection="snippets"
      action="delete"
      type="path"
      key="c:\inetpub\wwwroot\cfdocs\snippets"
      extensions=".cfm"
      recurse="no">
</cflock>

<!--- ACTION=DELETE, #4 (TYPE=PATH) (key is a query result set column) ---->
<cflock       name="verity"
      timeout="60">
<cfquery
      name="bookquery"
      datasource="book">
          select * from book where bookid='path1'
        </cfquery>
<cfoutput
      query="bookquery">
          --#url#,#description#-- <br>
</cfoutput>
<cfindex
      collection="snippets"
      action="delete"
      type="path"
      query="bookquery"
      key="description" >
</cflock>

<!--- ACTION=DELETE, #5 (TYPE=CUSTOM) ---->
<cflock name="verity"
      timeout="60">
<cfquery       name="book"
      datasource="book">
      select * from book where bookid='bookid1'
</cfquery>
<cfindex
      collection="custom_book"
      action="delete"
      type="custom"
      query="book"
      key="bookid" >
</cflock>

<!--- for ACTION=PURGE----------------------------------------------->
<cflock name="verity"
      timeout="60">
<cfindex
      action="purge"
      collection="snippets">
</cflock>


cfinput

Description

Used within the cfform tag, to place radio buttons, check boxes, or text boxes on a form. Provides input validation for the specified control type.

Category

Forms tags

Syntax

<cfinput
   type = "input_type"
   name = "name"
   value = "initial_value"
   required = "Yes" or "No"
   range = "min_value, max_value"
   validate = "data_type"
   onValidate = "javascript_function"
   pattern = "regexp"
   message = "validation_msg"
   onError = "text"
   size = "integer"
   maxLength = "integer"
   checked
   passThrough = "HTML_attributes">

See also

cfapplet , cfform , cfgrid , cfselect , cfslider , cftextinput , cftree

History

New in ColdFusion MX: if the cfform tag preserveData attribute is set to True, ColdFusion checks radio and checkbox values only if their value matches the posted value for the control. (In earlier releases, if the posted value did not match any of the cfinput checkboxes or radio buttons for the control, the checked attribute was used.

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
text
  • text: creates a text entry box control
  • radio: creates a radio button control
  • checkbox: creates a checkbox control
  • password: creates a password entry control
name
Required
Name for form input element.
value
Optional
Initial value for form input element.
required
Optional
No
  • Yes
  • No
range
Optional
Minimum and maximum value range, separated by a comma. If type = "text" or "password", this applies only to numeric data.
validate
Optional
Verifies a value’s format:
  • date: US date mm/dd/yyyy
  • eurodate: European date dd/mm/yyyy
  • time: time hh:mm:ss
  • float: floating point entry
  • integer: integer entry
  • telephone: telephone ###-###-####. Separator: hyphen or blank. Area code and exchange must begin with a digit 1 – 9.
  • zipcode: (U.S. formats only) 5-digit ##### or 9-digit #####-####. Separator: hyphen or blank.
  • creditcard: strips blanks and dashes; uses the mod10 algorithm.
  • social_security_number: ###-##-####. Separator: hyphen or blank.
  • regular_expression: matches input against regular expression specified by the pattern attribute.
onValidate
Optional
Custom JavaScript function to validate user input. The form object, input object, and input object values are passed to the routine, which should return True if validation succeeds, and False otherwise. If used, the validate attribute is ignored.
pattern
Required if validate = "regular_
expression"
JavaScript regular expression pattern to validate input. Omit leading and trailing slashes. For examples and syntax, see the "Building Dynamic Forms" chapter in Developing ColdFusion Applications.
message
Optional
Message text to display if validation fails.
onError
Optional
Custom JavaScript function to execute if validation fails.
size
Optional
Size of input control. Ignored, if type = "radio" or "checkbox".
maxLength
Optional
Maximum length of text entered, if type = "Text" or "password".
checked
Optional
Selects a control. No value is required.
Applies if type = "radio" or "checkbox".
Optional: you can enter the following values:
  • true (equivalent to checked)
  • false (equivalent to omitting the attribute)
passThrough
Optional
HTML attributes that are not supported by cfinput. If you specify an attribute and value, they are passed to the HTML code generated for the tag.

Usage

If the cfform preserveData attribute is true and the form posts back to the same page, the posted value of the cfinput control is used, instead of its Value or Checked attribute.

If cfinput checkbox or radio type values match the submitted value for the control, ColdFusion checks their values. If no value matches, nothing is checked.

To add other HTML <input> tag attributes and values to this tag, use the passThrough attribute. They are passed through ColdFusion to the browser when creating a form. The supported HTML attributes are: CLASS, ID, MAXLENGTH, MESSAGE, ONBLUR, ONCHANGE, ONCLICK, ONDBLCLICK, ONFOCUS, SIZE, STYLE, and TABINDEX.

If you specify a value in quotation marks, you must escape them; for example,

passThrough = "readonly = " "YES " " "

For more information, see cfform. For information on using JavaScript regular expressions with this tag, see Developing ColdFusion MX Applications with CFML.

Example

<!--- this example shows the use of cfinput within a cfform to ensure simple
validation of text items --->
<cfform action = "cfinput.cfm">
<!--- phone number validation --->
Phone Number Validation (enter a properly formatted phone number): <br>
<cfinput
   type = "Text" name = "MyPhone"
   message = "Enter telephone number,formatted xxx-xxx-xxxx (e.g. 617-761-2000)"
   validate = "telephone" required = "Yes">
   <font size = -1 color = red>Required</font>
<!--- zip code validation --->
<p>Zip Code Validation (enter a properly formatted zip code):<br>
<cfinput
   type = "Text" name = "MyZip"
   message = "Enter zip code, formatted xxxxx or xxxxx-xxxx"
   validate = "zipcode" required = "Yes">
   <font size = -1 color = red>Required</font>
<!--- range validation --->
<p>Range Validation (enter an integer from 1 to 5): <br>
<cfinput
   type = "Text" name = "MyRange" range = "1,5"
   message = "You must enter an integer from 1 to 5"
   validate = "integer" required = "No">
<!--- date validation --->
<p>Date Validation (enter a properly formatted date):<br>
<cfinput
   type = "Text" name = "MyDate"
   message = "Enter a correctly formatted date (dd/mm/yy)"
   validate = "date" required = "No">
<input
   type = "Submit" name = ""
   value = "send my information">
</cfform>


cfinsert

Description

Inserts records in data sources from data in a ColdFusion form or form Scope.

Category

Database manipulation tags

Syntax

<cfinsert
   dataSource = "ds_name"
   tableName = "tbl_name"
   tableOwner = "owner"
   tableQualifier = "tbl_qualifier"
   username = "username"
   password = "password"
   formFields = "formfield1, formfield2, ...">

See also

cfprocparam , cfprocresult , cfquery , cfqueryparam , cfstoredproc , cftransaction , cfupdate

History

New in ColdFusion MX: the connectString, dbName, dbServer, dbtype, provider and providerDSN attributes are deprecated. Do not use them. They do not work, and might cause an error, in releases later than ColdFusion 5.

Attributes

Attribute | Req/Opt | Default | Description
dataSource | Required |  | Data source; contains table.
tableName | Required |  | Table in which to insert form fields. ORACLE drivers: must be uppercase. Sybase driver:case-sensitive. Must be the same case used when table was created
tableOwner | Optional |  | For data sources that support table ownership (such as SQL Server, Oracle, and Sybase SQL Anywhere), use this field to specify the owner of the table.
tableQualifier | Optional |  | For data sources that support table qualifiers, use this field to specify qualifier for table. The purpose of table qualifiers varies among drivers. For SQL Server and Oracle, qualifier refers to name of database that contains table. For Intersolv dBASE driver, qualifier refers to directory where DBF files are located.
username | Optional |  | Overrides username specified in ODBC setup.
password | Optional |  | Overrides password specified in ODBC setup.
formFields | Optional | (all on form, except keys) | Comma-delimited list of form fields to insert. If not specified, all fields in the form are included. If a form field is not matched by a column name in the database, ColdFusion throws an error. The database table key field must be present in the form. It may be hidden.

Example

<!--- This shows how to use cfinsert instead of cfquery to put
data in a datasource. --->
<!--- if form.POSTED exists, we insert new record, so begin cfinsert tag --->
<cfif IsDefined ("form.posted")>
   <cfinsert dataSource = "cfsnippets"
      tableName = "Comments"
      formFields = "Email,FromUser,Subject,MessText,Posted">
   <h3><I>Your record was added to the database.</i></h3>
</cfif>

<cfif IsDefined ("form.posted")>
   <cfif Server.OS.Name IS "Windows NT">
      <cfinsert datasource="cfsnippets" tablename="Comments"
         formfields="EMail,FromUser,Subject,MessText,Posted">
   <cfelse>
      <cfinsert datasource="cfsnippets" tablename="Comments"
         formfields="CommentID,EMail,FromUser,Subject,MessText,Posted">
   </cfif>
   <h3><i>Your record was added to the database.</i></h3> </cfif>

<!--- use a query to show the existing state of the database --->
<cfquery name = "GetComments" dataSource = "cfsnippets">
   SELECT
      CommentID, EMail, FromUser, Subject, CommtType, MessText, Posted, Processed
   FROM
      Comments
</cfquery>

<html>
<head></head>
<h3>cfinsert Example</h3>
<p>First, show a list of the comments in the cfsnippets datasource.
<!--- show all the comments in the db --->
<table>
   <tr>
      <td>From User</td><td>Subject</td><td>Comment Type</td>
      <td>Message</td><td>Date Posted</td>
   </tr>
   <cfoutput query = "GetComments">
      <tr>
         <td valign = top><a href = "mailto:#Email#">#FromUser#</A></td>
         <td valign = top>#Subject#</td>
         <td valign = top>#CommtType#</td>
         <td valign = top><font size = "-2">#Left(MessText, 125)#</font></td>
         <td valign = top>#Posted#</td>
      </tr>
   </cfoutput>
</table>
<p>Next, we’ll offer the opportunity to enter a comment:
<!--- make a form for input --->
<form action = "cfinsert.cfm" method = "post">
   <pre>
   Email:    <input type = "Text" name = "email">
   From:    <input type = "Text" name = "fromUser">
   Subject:<input type = "Text" name = "subject">
   Message:<textarea name = "MessText" COLS = "40" ROWS = "6"></textarea>
   Date Posted:    <cfoutput>#DateFormat(Now())#</cfoutput>
   <!--- dynamically determine today’s date --->
   <input type = "hidden"
      name = "posted" value = "<cfoutput>#Now()#</cfoutput>">
   </pre>
   <input type = "Submit"
      name = "" value = "insert my comment">
</form>


cfinvoke

Description

Invokes component methods from within a ColdFusion page or component. You use this tag to reference a WSDL file and consume a web service from within a block of CFML code.

This tag works as follows:

  • Instantiates a component or web service and invokes a method on it
  • Invokes a method on an instantiated component or web service

This tag can pass parameters to a method in the following ways:

  • With the cfinvokeargument tag
  • As named attribute-value pairs, one attribute per parameter
  • As a structure, in the argumentCollection attribute

Category

Extensibility tags

Syntax

<!--- Syntax 1 - this syntax invokes a method of a component --->
<cfinvoke
   component = "component name or reference"
   method = "method name"
   returnVariable = "variable name"
   argumentCollection = "argument collection"
   ...>
OR
<!--- Syntax 2 - this syntax can invoke a method of a component only
   from within the component. --->
<cfinvoke
   method = "method name"
   returnVariable = "variable name"
   argumentCollection = "argument collection"
   ...
>
OR
<!--- Syntax 3 - this syntax invokes a web service --->
<cfinvoke
   webservice = "URLtoWSDL_location"
   method = "operation_name"
   username = user name"
   password = "password"
   inputParam1 = "value1"
   inputParam2 = "value2"
   ...
   returnVariable = "var_name"
   ...>
OR
<!--- Syntax 4A - this syntax invokes a component.
This syntax shows instantiation with the cfobject tag.
This cfinvoke syntax applies to instantiating a component
with the cfobject tag and to instantiating a component
with the createobject function. --->
<cfobject
   component = "component name"
   name = "mystringname for instantiated object">
<cfinvoke
   <!--- value is object name, within pound signs --->
   component = "#mystringname for instantiated component#">
OR
<!--- Syntax 4B - this syntax invokes a web service.
This syntax shows instantiation with the cfobject tag.
This cfinvoke syntax applies to instantiating a web service
with the cfobject tag and to instantiating a web service
with the createobject function. --->
<cfobject
   webservice = "web service name"
   name = "mystringname for instantiated object"
   method = "operation_name">
<cfinvoke
   <!--- value is object name, within pound signs --->
   webservice = "#my stringname for instantiated web service#" >

See also

cfargument , cfcomponent , cffunction , cfinvokeargument , cfobject , cfproperty , cfreturn

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
component | See Usage section |  | String or component object; a reference to a component, or component to instantiate.
method | See Usage section |  | Name of a method. For a web service, the name of an operation.
returnVariable | Optional |  | Name of a variable for the invocation result.
argumentCollection | Optional |  | Name of a structure; associative array of arguments to pass to the method.
username | Optional |  | Overrides username specified in Administrator > Web Services.
password | Optional |  | Overrides password specified in Administrator > Web Services.
webservice | Required |  | The URL of the WSDL file for the web service.
input_params ... |  |  | Input parameters.

Usage

The following table shows which attributes of this tag are required:

Specifying this attribute is required, optional or unnecessary (blank): | For this cfinvoke tag syntax:
 | Syntax 1 | Syntax 2 | Syntax 3 | Syntax 4A | Syntax 4B
component | Required | Optional |  | Required |
method | Required | Required | Required |  | Required
returnVariable | Optional | Optional | Optional |  | Optional
argumentCollection | Optional | Optional | Optional |  | Optional
username |  |  | Optional |  | Optional
password |  |  | Optional |  | Optional
webservice |  |  | Required |  | Required
input_params ... | Optional | Optional | Optional |  | Optional

If the component attribute specifies a component name, the component with the corresponding name is instantiated, the requested method is invoked, and then the component instance is immediately destroyed. If the attribute contains a reference to an instantiated component object, no instantiation or destruction of the component occurs.

Method arguments can be passed in one of the following ways (and, if an argument is passed in more than one way with the same name, this order of precedence applies):

  1. Using the cfinvokeargument tag
  2. Passing directly as attributes of the cfinvoke tag (they cannot have the same name as a registered cfinvoke attribute: method, component, webservice, returnVariable)
  3. Passing as struct keys, using the argumentCollection attribute

For example, the params struct contains three keys: a=1, b=1, c=1. The following call is evaluated as if the arguments were passed to the method in the order a=3, b=2, c=1:

<cfinvoke ... a=2 b=2 argumentCollection=params>
      <cfinvokeargument name="a" value="3">
   </cfinvoke>

Note: The following cfinvoke tag attribute names are reserved; they cannot be used for parameter names: component, method, argumentCollection, and result.

Example 1

This example uses Syntax 1.

<!--- immediate instantiation and destruction --->
<cfinvoke
   component="nasdaq.quote"
   method="getLastTradePrice"
   returnVariable="res">
   <cfinvokeargument
      name="symbol"
      value="macr">
</cfinvoke>
<cfoutput>#res#</cfoutput>

Example 2

This example uses Syntax 1.

<!--- passing the arguments using argumentCollection --->
<cfset args = StructNew()>
<cfset args.symbol = "macr">
<cfinvoke
   component="nasdaq.quote"
   method="getLastTradePrice"
   argumentCollection="#args#"
   returnVariable="res">
<cfoutput>#res#</cfoutput>

Example 3

This example uses Syntax 2.

<!--- called only from within a component, MyComponent--->
<cfinvoke
   method = "a method name of MyComponent"
   returnVariable = "variable name">

Example 4

This example uses Syntax 3.

<!--- using cfinvoke to consume a web service using a ColdFusion component --->
<!--- put the following code in a ColdFusion page named wscfml.cfm:--->
<cfinvoke
   webservice='http://www.xmethods.net/sd/2001/BabelFishService.wsdl'
   method='BabelFish'
   translationmode="en_es"
   sourcedata="Hello world, friend"
   returnVariable='foo'>
<cfoutput>#foo#</cfoutput>

For more information on the BabelFish web service example, see Developing ColdFusion MX Applications with CFML.

Example 5

This example uses Syntax 4A.

<!--- separate instantiation and method invocation; useful for
   multiple invocations using different methods or values--->
<cfobject
   name="quoteService"
   component="nasdaq.quote">
<cfinvoke
   component="#quoteService#"
   method="getLastTradePrice"
   symbol="macr"
   returnVariable="res_macr">
<cfoutput>#res#</cfoutput>
<cfinvoke
   component="#quoteService#"
   method="getLastTradePrice"
   symbol="mot"
   returnVariable="res_mot">
<cfoutput>#res#</cfoutput>


cfinvokeargument

Description

Passes the name and value of a parameter to a component method or a web service. This tag is used within the cfinvoke tag.

Category

Extensibility tags

Syntax

<cfinvokeargument
   name="argument name"
   value="argument value">

See also

cfargument , cfcomponent , cffunction , cfinvoke , cfobject , cfproperty , cfreturn

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
name | Required |  | Argument name
value | Required |  | Argument value

Usage

You can code multiple name/value pairs within this tag.

Example 1

<cfinvoke
   component="nasdaq.quote"
   method="getLastTradePrice"
   returnVariable="res">
   <cfinvokeargument
      name="symbol" value="mot">
   <cfinvokeargument
      name="symbol"    value="macr">
</cfinvoke>

<cfoutput>#res#</cfoutput>

Example 2

<cfinvoke
   webservice ="http://www.xmethods.net/sd/2001/BabelFishService.wsdl"
   method ="BabelFish"
   returnVariable = "varName"
   >
   <cfinvokeargument
      name="translationmode" value="en_es">
   <cfinvokeargument
      name="sourcedata" value="Hello world, friend">
</cfinvoke>
<cfoutput>#varName#</cfoutput>


cfldap

Description

Provides an interface to a Lightweight Directory Access Protocol (LDAP) directory server, such as the Netscape Directory Server.

Category

Forms tags, Internet Protocol tags

Syntax

<cfldap
   server = "server_name"
   port = "port_number"
   username = "name"
   password = "password"
   action = "action"
   name = "name"
   timeout = "seconds"
   maxRows = "number"
   start = "distinguished_name"
   scope = "scope"
   attributes = "attribute, attribute"
   filter = "filter"
   sort = "attribute[, attribute]..."
   sortControl = "nocase" and/or "desc" or "asc"
   dn = "distinguished_name"
   startRow = "row_number"
   modifyType = "replace" or "add" or "delete"
   rebind = "Yes" or "No"
   referral = "number_of_allowed_hops"
   secure = "multi_field_security_string"
   separator = "separator_character"
   delimiter = "delimiter_character">

See also

cfftp , cfhttp , cfmail , cfmailparam , cfpop

History

New in ColdFusion MX:

  • This tag validates the query name in the name attribute.
  • This tag does not support client-side sorting of query results. (It supports server-side sorting; use the sort and sortcontrol attributes.)
  • Server-side sorting results might be sorted slightly differently than in ColdFusion 5. If you attempt a sort against a server that does not support it, ColdFusion MX throws an error.
  • The filterconfig and filterfile attributes are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases. If they are used, this tag throws an exception.

Attributes

Attribute
Req/Opt
Default
Description
server
Required
Host name or IP address of LDAP server.
port
Optional
389
Port
username
Required if secure = "CFSSL_BASIC"
(anonymous)
User ID
password
Required if secure = "CFSSL_BASIC"
Password that corresponds to user name.
If secure = "CFSSL_BASIC", V2 encrypts the password before transmission.
action
Optional
query
  • query: returns LDAP entry information only. Requires name, start, and attributes attributes.
  • add: adds LDAP entries to LDAP server. Requires attributes attribute.
  • modify: modifies LDAP entries, except distinguished name dn attribute, on LDAP server. Requires dn. See modifyType attribute.
  • modifyDN: modifies distinguished name attribute for LDAP entries on LDAP server. Requires dn.
  • delete: deletes LDAP entries on an LDAP server. Requires dn.
name
Required if action = "Query"
Name of LDAP query. The tag validates the value.
timeout
Optional
60
Maximum length of time, in seconds, to wait for LDAP processing.
maxRows
Optional
Maximum number of entries for LDAP queries.
start
Required if action = "Query"
Distinguished name of entry to be used to start a search.
scope
Optional
oneLevel
Scope of search, from entry specified in start attribute for action = "Query".
  • oneLevel: entries one level below entry.
  • base: only the entry.
  • subtree: entry and all levels below it.
attributes
Required if action = "Query", "Add", "ModifyDN", or "Modify"
For queries: comma-delimited list of attributes to return. For queries, to get all attributes, specify "*".
If action = "add" or "modify", you can specify a list of update columns. Separate attributes with a semicolon.
If action = "ModifyDN", ColdFusion passes attributes to the LDAP server without syntax checking.
filter
Optional
"objectclass = *"
Search criteria for action = "query".
List attributes in the form:
"(attribute operator value)" Example: "(sn = Smith)"
sort
Optional
Attribute(s) by which to sort query results. Use a comma delimiter.
sortControl
Optional
asc
  • nocase: case-insensitive sort
  • asc: ascending (a to z) case-sensitive sort
  • desc: descending (z to a) case-sensitive sort
You can enter a combination of sort types; for example, sortControl = "nocase, asc".
dn
Required if action = "Add", "Modify", "ModifyDN", or "delete"
Distinguished name, for update action. Example: "cn = Bob Jensen, o = Ace Industry, c = US"
startRow
Optional
1
Used with action = "query". First row of LDAP query to insert into a ColdFusion query.
modifyType
Optional
replace
How to process an attribute in a multi-value list.
  • add: appends it to any attributes
  • delete: deletes it from the set of attributes
  • replace: replaces it with specified attributes
You cannot add an attribute that is already present or that is empty.
rebind
Optional
No
  • Yes: attempt to rebind referral callback and reissue query by referred address using original credentials.
  • No: referred connections are anonymous
referral
Optional
Integer. Number of hops allowed in a referral. A value of 0 disables referred addresses for LDAP; no data is returned.
secure
Optional
Security to employ, and required information. One option:
  • CFSSL_BASIC; certificate_db
    • "CFSSL_BASIC" provides V2 SSL encryption and server authentication
    -certificate_db: certificate database file (Netscape cert7.db format). Absolute path or simple filename. See the Usage section.
separator
Optional
, [comma]
Delimiter to separate attribute values of multi-value attributes. Used by query, add, and modify actions, and by cfldap to output multi-value attributes.
For example, if $ (dollar sign), the attributes attribute could be "objectclass = top$person", where the first value of objectclass is "top", and the second value is "person". This avoids confusion if values include commas.
delimiter
Optional
Separator for attribute name-value pairs, if:
  • the attributes attribute specifies more than one item
  • an attribute has the delimiter semicolon. For example: mgrpmsgrejecttext;lang-en
Used by query, add, and modify actions, and by cfldap to output multi-value attributes.
For example, if $ (dollar sign), you could specify this list of pairs with attributes:
"cn = Double Tree Inn$street = 1111 Elm;Suite 100

Usage

If you use the query action, cfldap creates a query object, allowing access to information in the query variables, as follows:

Variable name
Description
queryname.recordCount
Number of records returned by query
queryname.currentRow
Current row of query that cfoutput is processing
queryname.columnList
Column names in query

To use the security = "CFSSL_BASIC" option, you must copy the cert7.db and/or key3.db key files to the default directory location of a user-installed LDAP directory; on Windows, the directory is C:\cfusion\ldap.

The security certificate encrypts conversation. The server always sends a digital certificate to confirm the server.

Characters that are illegal in ColdFusion can be used in LDAP attribute names. As a result, the cfldap tag could create columns in the query result set whose names contain illegal characters and are, therefore, inaccessible in CFML. In ColdFusion, illegal characters are automatically mapped to the underscore character; therefore, column names in the query result set might not exactly match the names of the LDAP attributes.

For usage examples, see Developing ColdFusion MX Applications with CFML.

Example

<h3>cfldap Example</h3>
<p>Provides an interface to LDAP directory servers like BigFoot
(<a href = "http://www.bigfoot.com">http://www.bigfoot.com</A>).
<p>Enter a name (try your own name) and search a public LDAP resource.
<!--- If the server has been defined, run the query --->
<cfif IsDefined("form.server")>
   <!--- check to see that there is a name listed --->
   <cfif form.name is not "">
      <!--- make the LDAP query --->
      <cfldap     server = "ldap.bigfoot.com"
          action = "query"
          name = "results"
          start = "cn = #name#,c = US"
          filter = "(cn = #name#)"
          attributes = "cn,o,l,st,c,mail,telephonenumber"
          sort = "cn ASC">
      <!--- Display results --->
      <center>
      <table border = 0 cellspacing = 2 cellpadding = 2>
         <tr>
            <th colspan = 5>
               <cfoutput>#results.recordCount# matches found
               </cfoutput></TH>
         </tr>
         <tr>
            <th><font size = "-2">Name</font></TH>
            <th><font size = "-2">Organization</font></TH>
            <th><font size = "-2">Location</font></TH>
            <th><font size = "-2">E-Mail</font></TH>
            <th><font size = "-2">Phone</font></TH>
         </tr>
         <cfoutput query = "results">
            <tr>
               <td><font size = "-2">#cn#</font></td>
               <td><font size = "-2">#o#</font></td>
               <td><font size = "-2">#l#, #st#, #c#</font></td>
               <td><font size = "-2">
                  <A href = "mailto:#mail#">#mail#</A></font></td>
               <td><font size = "-2">#telephonenumber#</font></td>
            </tr>
         </cfoutput>
         </table>
         </center>
      </cfif>
</cfif>


cflocation

Description

Stops page execution and opens a ColdFusion page or HTML file.

Category

Flow-control tags, Page processing tags

Syntax

<cflocation
   url = "url"
   addToken = "Yes" or "No">

See also

cfabort , cfbreak , cfexecute , cfexit , cfif , cfloop , cfswitch , cfthrow , cftry

Attributes

Attribute
Req/Opt
Default
Description
url
Required
URL of HTML file or CFML page to open.
addToken
Optional
clientManagement must be enabled (see cfapplication).
  • Yes: appends client variable information to URL
  • No

Usage

You might write a standard message or response in a file, and call it from several applications. You could use this tag to redirect the user’s browser to the standard file.

If you use this tag after the cfflush tag on a page, an error is thrown.

Warning:Do not set a cookie variable on a page on which you use this tag. If you do, the cookie is not saved on the browser. Similarly, if you use a cookie to store a client variable, the client variable is not set.

Example

<!--- This view-only example shows the use of cflocation --->
<h3>cflocation Example</h3>
<p>This tag redirects the browser to a web resource; normally, you would
use this tag to go to a CF page or an HTML file on the same server.
The addToken attribute lets you send client information to the
target page.
<p>This code redirects you to CFDOCS home page (if you remove the comment
marks, this information displays in frame):
<!--- <cflocation url = "../cfdocs/index.htm" addToken = "No"> --->


cflock

Description

Ensures the integrity of shared data. Instantiates the following kinds of locks:

  • Exclusive: allows single-thread access to the CFML constructs in its body. The tag body can be executed by one request at a time. No other requests can start executing within the tag while a request has an exclusive lock. ColdFusion issues exclusive locks on a first-come, first-served basis.
  • Read-only: allows multiple requests to access CFML constructs within the tag body concurrently. Use a read-only lock only when shared data is read and not modified. If another request has an exclusive lock on shared data, the new request waits for the exclusive lock to be released.

Category

Application framework tags

Syntax

<cflock
   timeout = "timeout in seconds "
   scope = "Application" or "Server" or "Session"
   name = "lockname"
   throwOnTimeout = "Yes" or "No"
   type = "readOnly" or "exclusive ">
   <!--- CFML to be synchronized --->
</cflock>

See also

cfapplication , cfassociate , cfmodule

Attributes

Attribute
Req/Opt
Default
Description
timeout
Required
Maximum length of time, in seconds, to wait to obtain a lock. If lock obtained, tag execution continues. Otherwise, behavior depends on throwOnTimeout attribute value.
scope
Optional
Mutually exclusive with the name attribute.
  • Application
  • Server
  • Session
name
Optional
Lock name. Only one request can execute within this tag with a given name. Permits synchronizing access to resources from different parts of an application. Lock names are global to a ColdFusion server. They are shared among applications and user sessions, but not clustered servers. Mutually exclusive with the scope attribute. Cannot be an empty string.
throwOnTimeout
Optional
Yes
How timeout conditions are handled.
  • Yes: exception is generated for the timeout.
  • No: execution continues past this tag.
type
Optional
Exclusive
  • read-only: lets more than one request read shared data.
  • exclusive: lets one request read or write shared data.

Note: Limit the scope of code that updates shared data structures, files, and CFXs. Exclusive locks are required to ensure the integrity of updates, but read-only locks are faster. In a performance-sensitive application, substitute read-only locks for exclusive locks where possible; for example, when reading shared data.

Usage

ColdFusion Server is a multithreaded server; it can process multiple page requests at a time. USe the cflock tag for these purposes:

  • To ensure that modifications to shared data and objects made in concurrently executing requests occur sequentially.
  • Around file manipulation constructs, to ensure that file updates do not fail because files are open for writing by other applications or tags.
  • Around CFX invocations, to ensure that ColdFusion can safely invoke CFXs that are not implemented in a thread-safe manner. (This applies only to CFXs developed in C++ using the CFAPI.)

To work safely with ColdFusion, a C++ CFX that maintains and manipulates shared (global) data structures must be made thread-safe; however, this requires advanced knowledge. You can use a CFML custom tag wrapper around a CFX to make its invocation thread-safe.

Scope

When you display, set, or update variables in a shared scope, use the scope attribute to identify the scope as Server, Application or Session.

In the ColdFusion Administrator, Server section, the Locking page sets locking options according to scope. The following features are available for Server, Application, and Session scope:

 | Availability
Feature | Server | Application | Session
No automatic checking or locking | Yes | Yes | Yes
Full checking | Yes | Yes | Yes
Automatic read locking | Yes | Yes | Yes
Single threaded sessions |  |  | Yes

These feature have the following tradeoffs:

  • No automatic checking or locking: Reads and writes are not locked nor checked for correct protection. Select this only if you have run with full checking and know that there are no errors to handle, and that all locking is handled programmatically. This provides the fastest performance.
  • Full checking: All unlocked accesses are detected. Select this when in debug mode. This slows performance.
  • Automatic read locking: Reads are locked. Unlocked writes cause an error. This feature slows performance considerably.
  • Single-threaded sessions: The request must finish before another request for the same session is processed. This feature might slow performance, depending on the request pattern. For example, the total response time might increase if an application has multiple frames that can be refreshed at once, causing multiple requests to queue.

For more information, see Administering ColdFusion MX.

If you create a lock with the name attribute, and enable full lock checking in the ColdFusion Administrator, ColdFusion returns an error.

Do not specify full checking for a lock in its own scope; for example, if the lock is in the Application scope, do not specify full checking for the Application scope.

Deadlocks

A deadlock is a state in which no request can execute the locked section of a page. Once a deadlock occurs, neither user can break it, because all requests to the protected section of the page are blocked until the deadlock can be resolved by a lock timeout.

The cflock tag uses kernel level synchronization objects that are released automatically upon timeout and/or the abnormal termination of the thread that owns them. Therefore, while processing a cflock tag, ColdFusion never deadlocks for an infinite period of time. However, very large timeouts can block request threads for long periods, and radically decrease throughput. To prevent this, always use the minimum timeout value.

Another cause of blocked request threads is inconsistent nesting of cflock tags and inconsistent naming of locks. If you nest locks, everyone accessing the locked variables must consistently nest cflock tags in the same order. Otherwise, a deadlock can occur.

These examples show situations that cause deadlocks:

Example deadlock with two users
User 1 | User 2
Locks the session scope. | Locks the Application scope.
Deadlock: Tries to lock the Application scope, but it is already locked by User 2. | Deadlock: Tries to lock the Session scope, but it is already locked by User 1.

The following deadlock could occur if you tried to nest a write lock after a read lock:

Example deadlock with one user
User 1
Locks the Session scope with a read lock.
Attempts to lock the Session scope with an exclusive lock.
Deadlock: Attempts to lock the Session scope with an exclusive lock, but cannot because the scope is already locked for reading.

The following code shows this scenario:

<cflock timeout = "60" scope = "SESSION" type = "readOnly">
   ...............
   <cflock timeout = "60" scope = "SESSION" type = "Exclusive">
   .........
   </cflock>
</cflock>

To avoid a deadlock, everyone who nests locks must do so in a well-specified order and name the locks consistently. If you must lock access to the Server, Application, and Session scopes, you must do so in this order:

  1. Lock the Session scope. In the cflock tag, specify scope = "session".
  2. Lock the Application scope. In the cflock tag, specify scope = "Application".
  3. Lock the Server scope. In the cflock tag, specify scope = "server".
  4. Unlock the Server scope.
  5. Unlock the Application scope.
  6. Unlock the Session scope.

Note: If you do not have to lock a scope, you can skip any pair of these lock/unlock steps. For example, if you do not have to lock the Server scope, you can skip Steps 3 and 4. Similar rules apply for named locks.

For more information, see the following:

  • Developing ColdFusion MX Applications with CFML
  • Article #20370, ColdFusion Locking Best Practices, on the Macromedia website at http://www.macromedia.com/support/service/.

Example

<!--- This example shows how cflock can guarantee consistency of data updates
to variables in the Application, Server, and Session scopes. --->
<!----  Copy the following code into an Application.cfm file in the application
root directory. ----->
<!-------------------------------   beginning of Application.cfm code
   <h3>cfapplication Example</h3>
   <p>cfapplication defines scoping for a ColdFusion application and
enables or disables storing of application and session variables.
Put this tag in a special file called Application.cfm. It is run before
any other CF page in its directory.</p>
   <cfapplication name = "ETurtle"
sessionTimeout = #CreateTimeSpan(0,0, 0, 60)#
sessionManagement = "Yes">
<!--- Initialize session and application variables used by E-Turtleneck.
Use session scope for the session variables. --->
   <cflock scope = "Session"
      timeout = "30" type = "Exclusive">
      <cfif NOT IsDefined("session.size")>
         <cfset session.size = "">
      </cfif>
      <cfif NOT IsDefined("session.color")>
         <cfset session.color = "">
      </cfif>
   </cflock>
<!--- Use application lock for application variable. Variable keeps track
of number of turtlenecks sold. The application lock should have
the same name as specified in the cfapplication tag. ---->
   <cflock scope = "Application"       timeout = "30" type = "Exclusive">
      <cfif NOT IsDefined("application.number")>
         <cfset application.number = 1>
      </cfif>
   </cflock>
   <cflock scope = "Application" timeout = "30" type = "readOnly">
      <cfoutput>
         E-Turtleneck has sold #application.number# turtlenecks to date.
      </cfoutput>
  </cflock>
-------------------- End of Application.cfm ----------------------->
<h3>cflock Example</h3>
<cfif IsDefined("form.submit")>
   <cfoutput>
      Thanks for shopping E-Turtleneck. You chose size <b>#form.size#</b>,
color <b>#form.color#</b>.    </cfoutput>
   <!---    Lock session variables to assign form values to them. ---->
   <cflock scope = "Session" timeout = "30" type = "Exclusive">
      <cfparam name = session.size Default = #form.size#>
      <cfparam name = session.color Default = #form.color#>
   </cflock>
   <!---- Lock variable application.number to find total turtlenecks sold. --->
   <cflock scope = "Application" timeout = "30" type = "Exclusive">
      <cfset application.number = application.number + 1>
   </cflock>
<cfelse><!--- Show the form only if it has not been submitted. --->
   <form action = "cflock.cfm">
   <p>Congratulations! You selected the most comfortable turtleneck in the world.
Please select color and size.</p>
   <table cellspacing = "2" cellpadding = "2" border = "0">
      <tr>
         <td>Select a color.</td>
         <td><select type = "Text" name = "color">
               <option>red
               <option>white
               <option>blue
               <option>turquoise
               <option>black
               <option>forest green
            </select>
         </td>
      </tr>
      <tr>
         <td>Select a size.</td>
         <td><select type = "Text" name = "size" >
               <option>XXsmall
               <option>Xsmall
               <option>small
               <option>medium
               <option>large
               <option>Xlarge
            </select>
         </td>
      </tr>
      <tr>
         <td>Press Submit when you are finished making your selection.</td>
         <td><input type = "Submit" name = "submit" value = "Submit"> </td>
      </tr>
   </table>
   </form>
</cfif>


cflog

Description

Writes a message to a log file.

Category

Data output tags

Syntax

<cflog
   text = "text"
   log = "log type"
   file = "filename"
   type = "message type"
   application = "application name yes or no">

See also

cfcol , cfcontent , cfoutput , cftable

History

New in ColdFusion MX: The thread, date, and time attributes are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases. (In earlier releases, these attributes determined whether the respective data items were output to the log. In ColdFusion MX, this data is always output.)

Attributes

Attribute
Req/Opt
Default
Description
text
Required
Message text to log.
log
Optional
If you omit the file attribute, writes messages to standard log file. Ignored, if you specify file attribute.
  • Application: writes to Application.log, normally used for application-specific messages.
  • Scheduler: writes to Scheduler.log, normally used to log the execution of scheduled tasks.
file
Optional
Message file. Specify only the main part of the filename. For example, to log to the Testing.log file, specify "Testing".
The file must be located in the default log directory. You cannot specify a directory path. If the file does not exist, it is created automatically, with the suffix .log.
type
Optional
Information
Type (severity) of the message:
  • Information
  • Warning
  • Error
  • Fatal Information
application
Optional
Yes
  • Yes: log application name, if it is specified in a cfapplication tag.
  • No

Usage

This tag logs custom messages to standard or custom log files. You can specify a file for the log message or send messages to the default application or scheduler log. The log message can include ColdFusion expressions. Log files must have the suffix .log and must be located in the ColdFusion log directory.

Log entries are written as comma-delimited lists with these fields:

  • type
  • thread
  • date
  • time
  • application
  • text

Values are enclosed in double quotation marks. If you specify No for the application attribute, the corresponding entry in the list is empty.

You can disable cflog tag execution. For more information, see the ColdFusion Administrator, Basic Security page.

The following example logs the name of a user that logs on an application. The message is logged to the file myAppLog.log in the ColdFusion log directory. It includes the date, time, and thread ID, but not the application name.

<Cflog file="myAppLog" application="No"
   text="User #Form.username# logged on.">

For example, if a user enters "Sang Thornfield" in a form’s username field, this entry is added to the myApplog.log file entry:

"Information","153","02/28/01","14:53:40",,"User Sang Thornfield logged on."


cflogin

Description

A container for user login and authentication code. ColdFusion checks the user-provided ID and password against a data source, LDAP directory, or other repository of login identification. Used with cfloginuser tag.

Category

Extensibility tags

Syntax

<cflogin
   idletimeout = "value"
   applicationToken = "token"
   cookieDomain = "domain"
   ...
   <cfloginuser
      name = "name"
      password = "password-string"
      roles = "roles">
   ...>
</cflogin>

See also

cfloginuser , cflogout

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
idletimout | Optional | 1800 | Time interval with no keyboard activity after which ColdFusion logs the user off. Seconds.
applicationtoken | Optional | the application name | Unique application identifier. Limits the login scope to an application context, so that logins cannot be created illegally.
cookiedomain | Optional |  | Domain for which the security cookie is valid.

Usage

The body of this tag executes only if there is no logged-in user. When using application-based security, you put code in the body of the cflogin tag to check the user-provided ID and password against a data source, LDAP directory, or other repository of login identification. The body must include a cfloginuser tag to establish the authenticated user's identity in ColdFusion.

The following example shows a simple authentication. This code is typically in the application.cfm page.

Example

<cflogin>
   <cfloginuser
      name  = "foo"
      password ="bar"
      roles = "admin">
</cflogin>
<cfoutput>Authorized user: #getAuthUser()#</cfoutput>
<cflogout>
<cfoutput>Authorized user: #getAuthUser()#</cfoutput>


cfloginuser

Description

Identifies an authenticated user to ColdFusion. Specifies the user ID and roles. Used within a cflogin tag.

Category

Extensibility tags

Syntax

<cfloginuser
   name = "name"
   password = "password-string"
   roles = "roles">

See also

cflogin , cflogout

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
name | Required |  | A username.
password | Required |  | A user password.
roles | Required |  | A comma-delimited list of role identifiers. ColdFusion processes spaces in a list element as part of the element.

Usage

If Basic HTTP Authentication is in use, ColdFusion checks the standard security data in the request header. The Cflogin scope within this tag contains the user name and password in the cflogin.name and cflogin.password variables.

Example

See cflogin.


cflogout

Description

Logs the current user out. Removes knowledge of the user ID and roles from the server. If you do not use this tag, the user is automatically logged out when the session ends.

Category

Extensibility tags

Syntax

<cflogout>

See also

cflogin , cfloginuser

History

New in ColdFusion MX: This tag is new.

Example

<cflogin>
   <cfloginuser
      name  = "foo"
      password ="bar"
      roles = "admin">
</cflogin>
<cfoutput>Authorized user: #getAuthUser()#</cfoutput>
<cflogout>
<cfoutput>Authorized user: #getAuthUser()#</cfoutput>


cfloop

Description

Looping is a programming technique that repeats a set of instructions or displays output repeatedly until one or more conditions are met. This tag supports the following types of loops:

  • cfloop: index loop
  • cfloop: conditional loop
  • cfloop: looping over a query
  • cfloop: looping over a list or file
  • cfloop: looping over a COM collection or structure

Category

Flow-control tags


cfloop: index loop

Description

An index loop repeats for a number of times that is determined by a numeric value. An index loop is also known as a FOR loop.

Syntax

<cfloop
   index = "parameter_name"
   from = "beginning_value"
   to = "ending_value"
   step = "increment">
   ... HTML or CFML code ...
</cfloop>

See also

cfabort , cfbreak , cfexecute , cfexit , cfif , cflocation , cfrethrow , cfswitch , cfthrow , cftry

Attributes

Attribute | Req/Opt | Default | Description
index | Required |  | Index value. ColdFusion sets it to from value and increments or decrements by step value, until it equals to value.
from | Required |  | Beginning value of index.
to | Required |  | Ending value of index.
step | Optional | 1 | Step by which to increment or decrement the index value.

Usage

Using anything other than integer values in the from and to attributes of an index loop can product unexpected results. For example, if you increment through an index loop from 1 to 2, with a step of 0.1, ColdFusion outputs "1,1.1,1.2,...,1.9", but not "2". This is a programming language problem regarding the internal representation of floating point numbers.

Note: The to value is evaluated once, when the cfloop tag is encountered. Any change to this value within the loop block, or within the expression that evaluates to this value, does not affect the number of times the loop is executed.

Example

In this example, the code loops five times, displaying the index value each time:

<cfloop index = "LoopCount" from = "1" to = "5">
   The loop index is <cfoutput>#LoopCount#</cfoutput>.<br>
</cfloop>

The output of this loop is as follows:

The loop index is 1.
The loop index is 2.
The loop index is 3.
The loop index is 4.
The loop index is 5.

In this example, the code loops four times, displaying the index value each time. The value of j is decreased by one for each iteration. This does not affect the value of to, because it is a copy of j that is made before entering the loop.

<cfset j = 4>
<cfloop index = "LoopCount" from = "1" to = #j#>
   <cfoutput>The loop index is #LoopCount#</cfoutput>.<br>
   <cfset j = j - 1>
</cfloop>

The output of this loop is as follows:

The loop index is 1.
The loop index is 2.
The loop index is 3.
The loop index is 4.

As before, the value of j is decremented by one for each iteration, but this does not affect the value of to, because its value is a copy of j that is made before the loop is entered.

In this example, step has the default value, 1. The code decrements the index:

<cfloop index = "LoopCount"
   from = "5"
   to = "1"
   step = "-1">
The loop index is <cfoutput>#LoopCount#</cfoutput>.<br>
</cfloop>

The output of this loop is as follows:

The loop index is 5.
The loop index is 4.
The loop index is 3.
The loop index is 2.
The loop index is 1.


cfloop: conditional loop

Description

A conditional loop iterates over a set of instructions as long as a condition is True. To use this type of loop correctly, the instructions must change the condition every time the loop iterates, until the condition is False. Conditional loops are known as WHILE loops, as in, "loop WHILE this condition is true."

Syntax

<cfloop
   condition = "expression">
   ...
</cfloop>

See also

cfabort , cfbreak , cfexecute , cfexit , cfif , cflocation , cfswitch , cfthrow , cftry

Attributes

Attribute | Req/Opt | Default | Description
condition | Required |  | Condition that controls the loop.

Example

The following example increments CountVar from 1 to 5.

<!--- Set the variable CountVar to 0 --->
<cfset CountVar = 0>
<!--- Loop until CountVar = 5 --->
<cfloop condition = "CountVar LESS THAN OR EQUAL TO 5">
   <cfset CountVar = CountVar + 1>
   The loop index is <cfoutput>#CountVar#</cfoutput>.<br>
</cfloop>

The output of this loop is as follows:

The loop index is 1.
The loop index is 2.
The loop index is 3.
The loop index is 4.
The loop index is 5.


cfloop: looping over a query

Description

A loop over a query executes for each record in a query record set. The results are similar to those of the cfoutput tag. During each iteration, the columns of the current row are available for output. The cfloop tag loops over tags that cannot be used within a cfoutput tag.

Syntax

<cfloop
   query = "query_name"
   startRow = "row_num"
   endRow = "row_num">
</cfloop>

See also

cfabort , cfbreak , cfexecute , cfexit , cfif , cflocation , cfoutput , cfswitch , cfthrow , cftry

History

New in ColdFusion MX: On Windows, if the cfdirectory tag action = "list", the cfdirectory tag does not return the directory entries "." (dot) or ".." (double dot), which represent "the current directory" and "the parent directory." (In earlier releases, ColdFusion returned all the entries.)

CFML code such as the following, which was acceptable in ColdFusion 5, may cause incorrect output in ColdFusion MX:

<cfdirectory action = "list" directory ="c:\" name="somename">
Files in c:\<br>
<cfloop query = "somename" startrow = 3>
   #name#<br> >

For more information, see cfdirectory.

Attributes

Attribute | Req/Opt | Default | Description
query | Required |  | Query that controls the loop.
startRow | Optional |  | First row of query that is included in the loop.
endRow | Optional |  | Last row of query that is included in the loop.

Example

This example shows a cfloop looping over a query the same way as a cfoutput tag that uses the query attribute:

<cfquery name = "MessageRecords"
   dataSource = "cfsnippets">
      SELECT * FROM Messages
</cfquery>
<cfloop query = "MessageRecords">
   <cfoutput>#Message_ID#</cfoutput><br>
</cfloop>

The cfloop tag also iterates over a record set with dynamic start and stop points. This gets the next n sets of records from a query. This example loops from the 10th through the 20th record returned by MyQuery:

<cfset Start = 10>
<cfset End = 20>
<cfloop query = "MyQuery"
   startRow = "#Start#"
   endRow = "#End#">
   <cfoutput>#MyQuery.MyColName#</cfoutput><br>
</cfloop>

The loop stops when there are no more records, or when the current record index is greater than the value of the endRow attribute.

The advantage of looping over a query is that you can use CFML tags that are not allowed in a cfoutput tag. The following example combines the pages that are returned by a query of a list of page names into one document, using the cfinclude tag.

<cfquery name = "GetTemplate"
   dataSource = "Library"
   maxRows = "5">
   SELECT    TemplateName
   FROM Templates
</cfquery>
<cfloop query = "TemplateName">
   <cfinclude template = "#TemplateName#">
</cfloop>


cfloop: looping over a list or file

Description

Looping over a list steps through elements contained in any of these entities:

  • A variable
  • A value that is returned from an expression
  • A file

Syntax

<cfloop
   index = "index_name"
   list = "list_items"
   delimiters = "item_delimiter">
   ...
</cfloop>

See also

cfabort , cfbreak , cfexecute , cfexit , cfif , cflocation , cfswitch , cfthrow , cftry

Attributes

Attribute | Req/Opt | Default | Description
index | Required |  | In a list loop, the variable to receive next list element.
list | Required |  | A list, variable, or file name; contains a list
delimiters | Optional |  | Character(s) that separates items in list

Example

This loop displays four names:

<cfloop index = "ListElement"
   list = "John,Paul,George,Ringo">
      <cfoutput>#ListElement#</cfoutput><br>
</cfloop>

You can put more than one character in the delimiters attribute, in any order. For example, this loop processes commas, colons, and slashes as list delimiters:

<cfloop index = "ListElement"
   list = "John/Paul,George::Ringo"
   delimiters = ",:/">
      <cfoutput>#ListElement#</cfoutput><br>
</cfloop>

ColdFusion skips the second and subsequent consecutive delimiters between list elements. Thus, in the example, the two colons between "George" and "Ringo" are processed as one delimiter.

To loop over each line of a file, use the tag this way:

<cfloop list="#theFile#"
   index="curLine"
   delimiters="#chr(10)##chr(13)#">
   ...
</cfloop>


cfloop: looping over a COM collection or structure

Description

The cfloop collection attribute loops over every object within a COM/DCOM collection object, or every element in a structure:

  • A COM/DCOM collection object is a set of similar items referenced as a group. For example, the group of open documents in an application is a collection.
  • A structure contains a related set of items, or it can be used as an associative array. Looping is particularly useful when using a structure as an associative array.

In the loop, each item is referenced by the variable name in the item attribute. The loop executes until all items have been accessed.

The collection attribute is used with the item attribute. In the example that follows, item is assigned a variable called file2, so that with each cycle in the cfloop, each item in the collection is referenced. In the cfoutput section, the name property of the file2 item is referenced for display.

Example

This example uses a COM object to output a list of files. In this example, FFunc is a collection of file2 objects.

<cfobject
   class = FileFunctions.files
   name = FFunc
   action = Create>
<cfset FFunc.Path = "c:\">
<cfset FFunc.Mask = "*.*" >
<cfset FFunc.attributes = 16 >
<cfset x = FFunc.GetFileList()>
<cfloop collection = #FFUNC# item = "file2">
   <cfoutput>      #file2.name# <br>    </cfoutput>
</cfloop>
<!---Loop through a structure that is used as an associative array: --->
...<!--- Create a structure and loop through its contents --->
<cfset Departments = StructNew()>
<cfset val = StructInsert(Departments, "John ", "Sales ")>
<cfset val = StructInsert(Departments, "Tom ", "Finance ")>
<cfset val = StructInsert(Departments, "Mike ", "Education ")>
<!--- Build a table to display the contents --->
<cfoutput>
<table cellpadding = "2 " cellspacing = "2 ">
   <tr>
      <td><b>Employee</b></td>
      <td><b>Dept.</b></td>
   </tr>
<!--- Use item to create the variable person to hold value of key as loop runs --->
<cfloop collection = #Departments# item = "person ">
   <tr>
      <td>#person#</td>
      <td>#StructFind(Departments, person)#</td>
   </tr>
</cfloop>
</table>
</cfoutput>

Previous


ColdFusion Tags: cfmail--cfscript


cfmail

Description

Sends a e-mail message that contains query output, using an SMTP server.

Category

Forms tags, Internet Protocol tags

Syntax

<cfmail
   to = "recipient"
   from = "sender"
   cc = "copy_to"
   bcc = "blind_copy_to"
   subject = "msg_subject"
   type = "msg_type"
   maxrows = "max_msgs"
   mimeattach = "path"
   query = "query_name"
   group = "query_column"
   groupcasesensitive = "yes" or "no"
   startrow = "query_row"
   server = "servername"
   port = "port_id"
   mailerid = "headerid"
   timeout = "seconds"
   spoolenable = "yes" or "no">

See also

cfftp , cfhttp , cfldap , cfmailparam , cfpop

History

New in ColdFusion MX: the SpoolEnable attribute is new.

Attributes

Attribute
Req/Opt
Default
Description
to
Required
Message recipient name(s).
  • Static address. For example, "support@macromedia.com"
  • Variable that contains an address. For example, "#Form.Email#".
  • Name of a query column that contains an address. For example, "#EMail#". An e-mail message is sent for each returned row.
from
Required
E-mail message sender:
  • A static string; for example, "support@mex.com"
  • A variable; for example, "#GetUser.EMailAddress#"
cc
Optional
Address(es) to which to copy the message.
bcc
Optional
Address(es) to which to copy the message, without listing them in the message header.
subject
Required
Message subject. Can be dynamically generated. For example, to send messages that give customers status updates, "Status of Order Number #Order_ID#".
type
Optional
Extended type attributes for message. Informs receiving e-mail client that message has embedded HTML tags to process. Used only by mail clients that support HTML.
  • HTML
maxRows
Optional
Maximum number of messages to send.
MIMEAttach
Optional
Path of file to attach to message. Attached file is MIME-encoded.
query
Optional
Name of cfquery from which to draw data for message(s). Use this attribute to send more than one message, or to send query results within a message.
group
Optional
CurrentRow
Query column to use when you group sets of records to send as a message. For example, to send a set of billing statements to a customer, group on "Customer_ID." Case-sensitive. Eliminates adjacent duplicates when data is sorted by the specified field.
groupCaseSensitive
Optional
Yes
Boolean. Whether to consider case when grouping. If the query attribute specifies a query object that was generated by a case-insensitive SQL query, set this attribute to No, to keep the record set intact.
startRow
Optional
1
Row in a query to start from.
server
Optional
SMTP server address to use for sending messages. Server must be specified here or in Administrator. A value here overrides the Administrator.
port
-1
TCP/IP port on which SMTP server listens for requests. This is normally 25.
mailerID
Optional
ColdFusion Application Server
Mailer ID to be passed in X-Mailer SMTP header, which identifies the mailer application.
timeout
Optional
-1
Number of seconds to wait before timing out connection to SMTP server.
spoolEnable
Optional
Yes
  • Yes: Saves a copy of the message until the sending operation is complete. May be slower than the No option.
  • No: Queues the message for sending, without storing a copy until the operation is complete.

Example

<h3>cfmail Example</h3>
<p>This view-only example shows the use of cfmail.
<!---
<cfif IsDefined("form.mailto")>
   <cfif form.mailto is not ""
            AND form.mailfrom is not ""
            AND form.Subject is not "">
      <cfmail to = "#form.mailto#"
          from = "#form.mailFrom#"
          subject = "#form.subject#">
            This message was sent by an automatic mailer built with cfmail:
            = = = = = = = = = = = = = = = = = = = = = = = = = = =
            #form.body#
      </cfmail>
      <h3>Thank you</h3>
      <p>Thank you, <cfoutput>#mailfrom#: your message, #subject#, has
            been sent to #mailto#</cfoutput>.
   </cfif>
</cfif>
<p>
<form action = "cfmail.cfm">
   <pre>
   TO:        <input type = "Text" name = "MailTo">
   FROM: <input type = "Text" name = "MailFrom">
   SUBJECT:    <input type = "Text" name = "Subject">
   <hr>
   MESSAGE BODY:
   <textarea name ="body" cols="40" rows="5" wrap="virtual"></textarea>
   </pre>
   <!--- establish required fields --->
   <input type = "hidden" name = "MailTo_required" value = "You must enter
a recipient">
   <input type = "hidden" name = "MailFrom_required" value = "You must
enter a sender">
   <input type = "hidden" name = "Subject_required" value = "You must enter
a subject">
   <input type = "hidden" name = "Body_required" value = "You must enter
some text">
   <p><input type = "Submit" name = "">
</form> --->
Next


cfmailparam

Description

Attaches a file or adds a header to an e-mail message. Used within the cfmail tag. You can use more than one cfmailparam tag within a cfmail tag.

Category

Forms tags, Internet Protocol tags

Syntax

<cfmail
   to = "recipient"
   subject = "msg_subject"
   from = "sender"
   ...more attributes... >

   <cfmailparam
      file = "file-name" >
   or
   <cfmailparam
      name = "header-name"
       value = "header-value" >
   ...
</cfmail>

See also

cfftp , cfhttp , cfldap , cfmail , cfpop

Attributes

Attribute | Req/Opt | Default | Description
file | Required if you do not specify name attribute |  | Attaches file to a message. Mutually exclusive with name attribute.
name | Required if you do not specify file attribute |  | Name of header. Case-insensitive. Mutually exclusive with file attribute.
value | Optional |  | Value of header.

Example

<h3>cfmailparam Example</h3>
<p>This view-only example uses cfmailparam to attach files and add header to
   a message.</p>
<cfmail from = "peter@domain.com" To = "paul@domain.com"
Subject = "See Important Attachments and Reply">
   <cfmailparam name = "Reply-To" value = "peter@domain.com">
   Please review the new logo. Tell us what you think.
   <cfmailparam file = "c:\work\readme.txt">
   <cfmailparam file = "c:\work\logo.gif">
</cfmail>


cfmodule

Description

Invokes a custom tag for use in ColdFusion application pages. This tag processes custom tag name conflicts.

For more information, see the "Creating and Using Custom CFML Tags" chapter, in Developing ColdFusion MX Applications with CFML.

Category

Application framework tags

Syntax

<cfmodule
   template = "path"
   name = "tag_name"
   attributeCollection = "collection_structure"
   attribute_name1 = "valuea"
   attribute_name2 = "valueb"
   ...>

See also

cfapplication , cfassociate , cflock

History

New in ColdFusion MX: When using this tag within a custom tag, if the attribute_name parameter is the same as a key element within the attributeCollection parameter, ColdFusion uses the name value that is within the attributeCollection parameter. (Earlier releases did not process this consistently.)

Attributes

Attribute
Req/Opt
Default
Description
template
Required unless name attribute is used
Mutually exclusive with the name attribute. A path to the page that implements the tag.
  • Relative path: expanded from the current page
  • Absolute path: expanded using ColdFusion mapping
A physical path is not valid.
name
Required unless template attribute is used
Mutually exclusive with the template attribute. A custom tag name, in the form "Name.Name.Name..." Identifies subdirectory, under the ColdFusion tag root directory, that contains custom tag page. For example (Windows format):
<cfmodule name = "macromedia.Forums40.
GetUserOptions">
This identifies the page GetUserOptions.cfm in the directory CustomTags\macromedia\Forums40 under the ColdFusion root directory.
attributeCollection
Optional
Structure. A collection of key-value pairs that represent attribute names and values. You can specify multiple key-value pairs. You can specify this attribute only once.
attribute_name
Optional
Attribute for a custom tag. You can include multiple instances of this attribute to specify the parameters of a custom tag.

Usage

To name a ColdFusion page that contains the custom tag definition, including its path, use the template attribute. To refer to the custom tag in the ColdFusion installation directory, using dot notation to indicate its location, use the name attribute.

You can use attributeCollection and attribute_name in the same call.

Within the custom tag code, the attributes passed with attributeCollection are saved as independent attribute values, with no indication that they are grouped into a structure by the custom tag’s caller.

Similarly, if the custom tag uses a cfassociate tag to save its attributes, the attributes passed with attributeCollection are saved as independent attribute values, with no indication that they are grouped into a structure by the custom tag’s caller.

Example

<h3>cfmodule Example</h3>
<p>This view-only example shows use of cfmodule to call a custom tag inline.</p>
<p>This example uses a sample custom tag that is saved in myTag.cfm in
the snippets directory. You can also save ColdFusion custom tags in the
Cfusion\CustomTags directory.
<cfset attrCollection1 = StructNew()>
<cfparam name="attrCollection1.value1" default="22">
<cfparam name="attrCollection1.value2" default="45">
<cfparam name="attrcollection1.value3" default="88">
<!--- Call the tag with CFMODULE with Name--->
<cfmodule
   Template="myTag.cfm"
   X="3"
   attributeCollection=#attrCollection1#
   Y="4">
<!--- show the code --->
<HR size="2" color="#0000A0">
<P>Here is one way in which to invoke the custom tag,
using the TEMPLATE attribute.</P>
<cfoutput>#HTMLCodeFormat(" <CFMODULE
   Template=""myTag.cfm""
   X=3
   attributeCollection=##attrCollection1##
   Y=4>")#
</cfoutput>
<P>The result: <cfoutput>#result#</cfoutput>
<!--- Call the tag with CFMODULE with Name--->
<!---
   <CFMODULE
      Name="myTag"
      X="3"
      attributeCollection=#attrCollection1#
      Y="4">
--->
<!--- show the code --->
<HR size="2" color="#0000A0">
<P>Here is another way to invoke the custom tag,
using the NAME attribute.</P>
<cfoutput>#HTMLCodeFormat(" <CFMODULE
      NAME='myTag'
      X=3
      attributeCollection=##attrCollection1##
      Y=4>")#
</cfoutput>
<P>The result: <cfoutput>#result#</cfoutput>
<!--- Call the tag using the short cut notation --->
<!---
<CF_myTag
   X="3"
   attributeCollection=#attrCollection1#
   Y="4">
--->

<!--- show the code --->
<p>Here is the short cut to invoking the same tag.</p>
<cfoutput>#HTMLCodeFormat(   "<cf_mytag
   x = 3
   attributeCollection = ##attrcollection1##
   y = 4>")#
</cfoutput>
<p>The result: <cfoutput>#result#</cfoutput></p>


cfobject

Description

Creates a ColdFusion object, of a specified type.

Note: You can enable and disable this tag in the ColdFusion Administrator page, under ColdFusion Basic Security, Tag Restrictions.

Category

Extensibility tags

Syntax

The tag syntax depends on the object type. Some types use the type attribute; others do not. See the following sections:

  • cfobject: COM object
  • cfobject: component object
  • cfobject: CORBA object
  • cfobject: Java or EJB object
  • cfobject: web service object

Note: On UNIX, this tag does not support COM objects.

See also

cfargument , cfcomponent , cffunction , cfinvoke , cfinvokeargument , cfproperty , cfreturn

History

New in ColdFusion MX: This tag, and the CreateObject function, can instantiate ColdFusion components (CFCs); you can use them within the cfscript tag.


cfobject: COM object

Description

Creates and manipulates a Component Object Model (COM) object. Invokes a registered automation server object type.

For information on OLEView, and about COM and DCOM, see the Microsoft OLE Development web site: http://www.microsoft.com.

To use this tag, you must provide the object’s program ID or filename, the methods and properties available through the IDispatch interface, and the arguments and return types of the object's methods. For most COM objects, you can get this information with the OLEView utility.

Note: On UNIX, this tag does not support COM objects.

Syntax

<cfobject
   type = "com"
   action = "action"
   class = "program_ID"
   name = "text"
   context = "context"
   server = "server_name">

See also

cfcollection , cfexecute , cfindex , cfreport , cfsearch , cfwddx

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
Object type:
  • com
  • corba
  • java
(The other object types do not take the type attribute.)
action
Required
  • create: instantiates a COM object (typically, a DLL) before invoking methods or properties.
  • connect: connects to a COM object (typically, an EXE) running on server.
class
Required
Component ProgID for the object to invoke.
name
Required
String; name for the instantiated component
context
Optional
  • inproc
  • local
  • remote
On Windows: If not specified, uses Registry setting.
server
Required if context = "Remote"
Server name, using Universal Naming Convention (UNC) or Domain Name Serve (DNS) convention, in one of these forms:
  • \\lanserver
  • lanserver
  • http://www.servername.com
  • www.servername.com
  • 127.0.0.1

Example

<h3>cfobject (COM) Example</h3>
<!--- Create a COM object as an inproc server (DLL). (class = prog-id)--->
<cfobject action = "Create"
   type = "COM"
   class = Allaire.DocEx1.1
   name = "obj">

<!--- Call a method. Methods that expect no arguments should be called
using empty parentheses. --->
<cfset obj.Init()>

<!--- This is a collection object. It should support, at a minimum:
   Property : Count
   Method : Item(inarg, outarg)
   and a special property called _NewEnum
--->
<cfoutput>
   This object has #obj.Count# items.
   <br> <HR>
</cfoutput>

<!--- Get the 3rd object in the collection. --->
<cfset emp = obj.Item(3)>
<cfoutput>
   The last name in the third item is #emp.lastname#.
   <br> <HR>
</cfoutput>
<!---Loop over all the objects in the collection.--->
<p>Looping through all items in the collection:
<br>
<cfloop
   collection = #obj#
   item = file2>
   <cfoutput>Last name: #file2.lastname# <br></cfoutput>
</cfloop>


cfobject: component object

Description

The cfobject tag can create a ColdFusion component (CFC) object.

Syntax

<cfobject
   name = "variable name"
   component = "component name">

See also

cfcollection , cfcomponent , cfexecute , cfindex , cfreport , cfsearch , cfwddx

Attributes

Attribute | Req/Opt | Default | Description
name | Required |  | String; name for the instantiated component. The name must not have a period as the first or last character.
component | Required |  | Name of component to instantiate

Usage

Executing operations on a CFC object executes CFML code that implements the CFC's method in the CFC file. Using this tag to instantiate a component returns a ComponentProxy object that can delegate control to a CFC page.

Example

<!--- separate instantiation and method invocation; permits multiple
invocations --->
<cfobject
name="quoteService"
component="nasdaq.quote">
<cfinvoke
component="#quoteService#"
method="getLastTradePrice"
symbol="macr"
returnVariable="res">
<cfoutput>#res#</cfoutput><br>

<cfinvoke
component="#quoteService#"
method="getLastTradePrice"
symbol="mot"
returnVariable="res">
<cfoutput>#res#</cfoutput>


cfobject: CORBA object

Description

Calls methods on a registered CORBA object.

Syntax

<cfobject
   type = "corba"
   context = "context"
   class = "file or naming service"
   name = "text"
   locale = "type-value arguments">

See also

cfcollection , cfexecute , cfindex , cfreport , cfsearch , cfwddx

History

New in ColdFusion MX: the Naming Service separator format for addresses has changed from a dot to a forward slash. For example, if "context=NameService", for a class, use either of the following formats for the class parameter:

  • "Macromedia/Eng/CF"
  • "Macromedia.current/Eng.current/CF"

(In earlier releases, the format was "Macromedia.Eng.CF".)

New in ColdFusion MX: the locale attribute specifies the Java config that contains the properties file.

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
Object type:
  • com
  • corba
  • java
(The other object types do not take the type attribute.)
context
Required
  • ior: ColdFusion uses Interoperable Object Reference (IOR) to access CORBA server.
  • nameservice: ColdFusion uses naming service to access server. This option is valid only with the InitialContext of a VisiBroker Orb.
class
Required
  • If context = "ior": absolute path of file that contains string version of the Interoperable Object Reference (IOR). ColdFusion must be able to read file; it should be local to ColdFusion server or accessible on network.
  • If context = "nameservice:" forward slash-delimited naming context for naming service. For example: Allaire//Doc/empobject
name
Required
String; name for the instantiated component. An application uses it to reference the CORBA object’s methods and attributes.
locale
Optional
Sets arguments for a call to init_orb. Use of this attribute is specific to VisiBroker ORBs. It is available on C++, Version 3.2. The value must be in the form:
locale = " -ORBagentAddr 199.99.129.33 -ORBagentPort 19000"
Each type-value pair must start with a hyphen.

Usage

ColdFusion Enterprise version 4.0 and later supports CORBA through the Dynamic Invocation Interface (DII). To use cfobject with CORBA objects, you must provide the name of the file that contains a string-formatted version of the IOR, or the object’s naming context in the naming service; and the object’s attributes, method names, and method signatures.

User-defined types (for example, structures) are not supported.

Example

<cfobject type = "corba"
  context = "ior"
  class = "c:\\myobject.ior"
  name = "GetName">


cfobject: Java or EJB object

Description

Creates and manipulates a Java and Enterprise Java Bean (EJB) object.

Syntax

<cfobject
   type = "Java"
   action = "Create"
   class = "Java class"
   name = "object name">

See also

cfcollection , cfexecute , cfindex , cfreport , cfsearch , cfwddx

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
Object type:
  • com
  • corba
  • java
(The other object types do not take the type attribute.)
action
Required
Create: Creates a Java or WebLogic Environment object.
class
Required
Java class.
name
Required
String; name for the instantiated component.

Usage

To call Java CFXs or Java objects, ColdFusion uses a Java Virtual Machine(JVM) that is embedded in the process. You can configure JVM loading, location and settings in the ColdFusion Administrator.

Any Java class available in the class path that is specified in the ColdFusion Administrator can be loaded and used from ColdFusion, using the cfobject tag.

To access Java methods and fields, do the following steps:

  1. Call the cfobject tag, to load the class. See the example code.
  2. Use the init method with appropriate arguments, to call a constructor. For example:
    3. <cfset ret = myObj.init(arg1, arg2)>

Calling a public method on the object without first calling the init method results in an implicit call to the default constructor. Arguments and return values can be any Java type (simple, array, object). ColdFusion makes the conversions if strings are passed as arguments, but not if they are received as return values.

Overloaded methods are supported if the number of arguments is different.


Calling EJBs

To create and call EJB objects, use the cfobject tag. In the second example below, the WebLogic JNDI is used to register and find EJBHome instances.

Example

<!--- Example of a Java Object his cfobject call loads the class MyClass
but does not create an instance object. Static methods and fields
are accessible after a call to cfobject. --->
<cfobject
   action = "create"
   type = "java"
   class = "myclass"
   name = "myobj">

<!---- Example of an EJB - The cfobject tag creates the Weblogic Environment
object, which is used to get InitialContext. The context object is
used to look up the EJBHome interface. The call to create() results
in getting an instance of stateless session EJB. --->

<cfobject
   action = "create"
   type = "java"
   class = "weblogic/jndi/Environment"
   name = "wlEnv">

<cfset ctx = wlEnv.getInitialContext()>
<cfset ejbHome = ctx.lookup("statelessSession.TraderHome")>
<cfset trader = ejbHome.Create()>
<cfset value = trader.shareValue(20, 55.45)>
<cfoutput>
    Share value = #value#
</cfoutput>
<cfset value = trader.remove()>


cfobject: web service object

Description

Creates a web service proxy object.

Syntax

<cfobject
   webservice= "http://....?wsdl" or "name set in Administrator"
   name = "myobjectname">

See also

cfcollection , cfexecute , cfindex , cfreport , cfsearch , cfwddx

Attributes

Attribute
Req/Opt
Default
Description
webservice
Required
URL to web service WSDL file.
  • Absolute URL of web service
  • Name (string) assigned in the Administrator to the web service
name
Required
Local name for the web service. String.

Usage

Instantiates a proxy object for a web service. You can enter the absolute URL in this tag, or refer to a web service that is entered in the ColdFusion Administrator. To minimize potential code maintenance, enter the web service in the Administrator, then refer to that name in this tag.


cfobjectcache

Description

Flushes the query cache.

Category

Database manipulation tags

Syntax

<cfobjectcache
   action = "clear">

See also

cfobject

History

This tag was added in ColdFusion 5.

Attributes

Attribute | Req/Opt | Default | Description
action | Required |  | clear: Clears queries from the cache in the Application scope


cfoutput

Description

Displays the results of a database query or other operation.

Category

Data output tags

Syntax

<cfoutput
   query = "query_name"
   group = "query_column"
   groupCaseSensitive = "Yes" or "No"
   startRow = "start_row"
   maxRows = "max_rows_output">
</cfoutput>

See also

cfcol , cfcontent , cfdirectory , cftable

History

New in ColdFusion MX: On Windows, if the cfdirectory tag action = "list", the tag does not return the directory entries "." (dot) or ".." (double dot), which represent "the current directory" and "the parent directory." (In earlier releases, it returned all the entries.)

CFML code such as the following, which was acceptable in ColdFusion 5, might cause incorrect output in ColdFusion MX:

<cfdirectory action = "list" directory="c:\" name="foo">
Files in c:\<br>
<cfoutput query="foo" startrow=3>
   #name#<br>
</cfoutput>

CFML code such as the following, which was acceptable in ColdFusion 5, is acceptable in ColdFusion MX, although it is unnecessary:

<cfdirectory directory="c:\" name="foo">
Files in c:\<br>
<cfoutput query="foo"
   <cfif NOT foo.name is "." AND NOT foo.name is "..">
      #name#<br>
   </cfif>
</cfoutput>

Attributes

Attribute | Req/Opt | Default | Description
query | Optional |  | Name of cfquery from which to draw data for output section.
group | Optional |  | Query column to use when you group sets of records. Use if you retrieved a record set ordered on a query column. For example, if a record set is ordered on "Customer_ID" in the cfquery tag, you can group the output on "Customer_ID." Case-sensitive. Eliminates adjacent duplicates when data is sorted.
groupCaseSensitive | Optional | Yes | Boolean. Whether to group by case. If the query attribute specifies a query object that was generated by a case-insensitive SQL query. To keep record set intact, set to "No".
startRow | Optional | 1 | Row from which to start output.
maxRows | Optional |  | Maximum number of rows to display.

Usage

To nest cfoutput blocks, you must specify the group and query attributes at the top-most level, and the group attribute for each inner block except the innermost cfoutput block.

This tag requires an end tag.

Example

<!--- run a sample query --->
<cfquery name = "GetCourses" dataSource = "cfsnippets">
   SELECT Dept_ID, CorName, CorLevel
   FROM courseList
   ORDER by Dept_ID, CorLevel, CorName
</cfquery>
<h3>cfoutput Example</h3>
<p>cfoutput tells ColdFusion Server to begin processing, and then
to hand back control of page rendering to the web server.
<p>For example, to show today’s date, you could write #DateFormat("#Now()#").
If you enclosed that expression in cfoutput, the result would be
<cfoutput>#DateFormat(Now())#</cfoutput>.

<p>In addition, cfoutput may be used to show the results of a query
operation, or only a partial result, as shown:

<p>There are <cfoutput>#getCourses.recordCount#</cfoutput> total records
in our query. Using the maxRows parameter, we are limiting our
display to 4 rows.
<p><cfoutput query = "GetCourses" maxRows = 4>
   <PRE>#Dept_ID#   #CorName#   #CorLevel#</PRE>
   </cfoutput>

<p>cfoutput can also show the results of a more complex expression,
such as getting the day of the week from today’s date. We first
extract the integer representing the Day of the Week from
the server function Now() and then apply the result to
the DayofWeekAsString function:

<br>Today is #DayofWeekAsString(DayofWeek(Now()))#
<br>Today is <cfoutput>#DayofWeekAsString(DayofWeek(Now()))#</cfoutput>


cfparam

Description

Tests for a parameter’s existence, tests its data type, and, if a default value is not assigned, provides one.

Category

Variable manipulation tags

Syntax

<cfparam
   name = "param_name"
   type = "data_type"
   default = "value">

See also

cfcookie , cfregistry , cfsavecontent , cfschedule , cfset

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of parameter to test (such as "Client.Email " or "Cookie.BackgroundColor "). If omitted, and if the parameter does not exist, an error is thrown.
type
Optional
  • any: any value
  • array: any array value
  • binary: a binary value
  • boolean: a Boolean value
  • date: a date-time value
  • numeric: a numeric value
  • query: a query object
  • string: a string value or single character
  • struct: a structure
  • UUID: a Universally Unique Identifier, formatted ‘XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXX’, where ‘X’ is a hex digit. See CreateUUID.
  • variableName: a variable name
default
Optional
Value to set parameter to if it does not exist.

Usage

You can use this tag to make the following tests:

  • To test whether a required variable exists, use this tag with only the name attribute. If it does not exist, ColdFusion Server stops processing the page and returns an error.
  • To test whether a required variable exists, and that it is of the specified type, use this tag with the name and type attributes. If the variable of the specified type does not exist, ColdFusion returns an error.
  • To test whether an optional variable exists, use this tag with the name and default attributes. If it does not exist, it is created and set to the value of the default attribute. If it exists, processing continues; the value is not changed.

Example

<!--- This example shows how to use CFPARAM to define default values for page
   variables -------->
<cfparam name = "storeTempVar" default = "my default value">
<cfparam name = "tempVar" default = "my default value">

<!--- check if form.tempVar was passed --->
<cfif IsDefined("form.tempVar") is "True">
   <!--- check if form.tempVar is not blank --->
   <cfif form.tempVar is not "">
      <!--- if not, set tempVar to value of form.tempVar --->
      <cfset tempVar = form.tempVar>
   </cfif>
</cfif>

<body>
<h3>cfparam Example</h3>
<p>cfparam is used to set default values so thata developer does not have to
check for the existence of a variable using a function like IsDefined.

<p>The default value of our tempVar is
   "<cfoutput>#StoreTempVar# </cfoutput>"

<!--- check if tempVar is still the same as StoreTempVar
and that tempVar is not blank --->
<cfif tempVar is not #StoreTempVar#
   and tempVar is not "">
      <h3>The value of tempVar has changed: the new value is
      <cfoutput>#tempVar#</cfoutput></h3>
</cfif>

<p>
<form action = "cfparam.cfm" method = "post">
   Type in a new value for tempVar, and hit submit:<br>
   <input type = "Text" name = "tempVar">
   <input type = "Submit" name = "" value = "submit">
</form>


cfpop

Description

Retrieves and deletes e-mail messages from a POP mail server.

Category

Forms tags, Internet Protocol tags

Syntax

<cfpop
   server = "servername"
   port = "port_number"
   username = "username"
   password = "password"
   action = "action"
   name = "queryname"
   messageNumber = "number"
   uid = "number"
   attachmentPath = "path"
   timeout = "seconds"
   maxRows = "number"
   startRow = "number"
   generateUniqueFilenames = "boolean">

See also

cfftp , cfhttp , cfldap , cfmail , cfmailparam , SetLocale

Attributes

Attribute
Req/Opt
Default
Description
server
Required
POP server identifier:
  • A host name; for example, "biff.upperlip.com"
  • An IP address; for example, "192.1.2.225"
port
Optional
110
POP port
username
Optional
Anonymous
  • A user name
  • "Anonymous"
password
Optional
Password that corresponds to username.
action
Optional
getHeaderOnly
  • getHeaderOnly: returns message header information only
  • getAll: returns message header information, message text, and attachments if attachmentPath is specified
  • delete: deletes messages on POP server
name
Required if action = "getAll" or "getHeaderOnly"
Name for index query.
messageNumber
If action = "delete", this attribute, or uid, is required
Message number or comma-delimited list of message numbers to get. Applies to action ="getAll" and "getHeaderOnly". For these actions, if it is omitted, all messages are returned. Invalid message numbers are ignored.
uid
If action = "delete", this attribute, or messageNumber, is required
UID or a comma-delimited list of UIDs to get. Applies to action = "getHeaderOnly" and action = "getAll". For these actions, if it is omitted, all messages are returned. Invalid UIDs are ignored.
attachmentPath
Optional
If action = "getAll", allows attachments to be written to directory. If this value is invalid, no attachment files are written to server.
timeout
Optional
60
Maximum time, in seconds, to wait for mail processing.
maxRows
Optional
999999
Number of messages to return, starting with the number in startRow. If messageNumber is specified, this attribute is ignored.
startRow
Optional
1
First row number to get. If messageNumber is specified, this attribute is ignored.
generateUniqueFilenames
Optional
No
  • Yes: Generate unique filenames for files attached to an e-mail message, to avoid naming conflicts when files are saved
  • No

Usage

Note: To optimize performance, two retrieve options are available. Message header information is typically short, and therefore quick to transfer. Message text and attachments can be very long, and therefore take longer to process.


cfpop query variables

The following table describes the query variables that are returned by cfpop:

Variable names | Description
queryname.recordCount | Number of records returned by query
queryname.currentRow | Current row that cfoutput is processing
queryname.columnList | List of column names in query
queryname.UID | Unique identifier for the email message file


Message header and body columns

The following table lists the message header and body columns that are returned if action = "getHeaderOnly" or "getAll":

Column Name | getHeaderOnly returns | getAll returns
queryname.date | yes | yes
queryname.from | yes | yes
queryname.messagenumber | yes | yes
queryname.replyto | yes | yes
queryname.subject | yes | yes
queryname.cc | yes | yes
queryname.to | yes | yes
queryname.body | not available | yes
queryname.header | not available | yes
queryname.attachments | not available | yes
queryname.attachmentfiles | not available | yes

To create a ColdFusion date/time object from the date-time string that is extracted from a mail message in the queryname.date column, use the following table:

Locale | How to create a ColdFusion date/time object from queryname.date
English (US) | Use the ParseDateTime function, which converts a date-time value to UTC
Other | Extract the date part of string; pass it to the LSParseDateTime function

Note: To set the default display format of date, time, number, and currency values, use the SetLocale function.

For more information on cfpop, see Developing ColdFusion MX Applications with CFML.

Example

<!--- This view-only example shows the use of cfpop --->
<h3>cfpop Example</h3>
<p>cfpop lets you retrieve and manipulate mail in a POP3 mailbox.
This view-only example shows how to create one feature of
a mail client, to display the mail headers in a POP3 mailbox.
<p>To execute this, un-comment this code and run with a mail-enabled CF Server.
<!---
<cfif IsDefined("form.server ")>
   <!--- make sure server, username are not empty --->
   <cfif form.server is not "" and form.username is not "">
      <cfpop server = "#server# " username = #UserName# password = #pwd#
      action = "GETHEADERONLY " name = "GetHeaders ">
      <h3>Message Headers in Your Inbox</h3>
      <p>Number of Records:
      <cfoutput>#GetHeaders.recordCount#</cfoutput></p>
      <ul>
         <cfoutput query = "GetHeaders">
         <li>Row: #currentRow#: From: #From# -- Subject: #Subject#
         </cfoutput>
      </ul>
   </cfif>
</cfif>

<form action = "cfpop.cfm " method = "post">
   <p>Enter your mail server:
   <p><input type = "Text" name = "server">
   <p>Enter your username:
   <p><input type = "Text" name = "username">
   <p>Enter your password:
   <p><input type = "password" name = "pwd">
   <input type = "Submit" name = "get message headers">
</form>
--->


cfprocessingdirective

Description

Determines whether to suppress the output of extra white space and other CFML output, within the Tag scope. Used with applications that depend on the whitespace characteristics of their output stream.

Category

Data output tags

Syntax

<cfprocessingdirective
   pageencoding = "page-encoding literal string">
or
<cfprocessingdirective
   suppressWhiteSpace = "Yes" or "No"
   pageEncoding = "page-encoding literal string">
   CFML tags
</cfprocessingdirective>

See also

cfcol , cfcontent , cfoutput , cfsetting , cftable

History

New in ColdFusion MX: You can specify the suppresswhitespace attribute value as a literal string variable. (ColdFusion 5 supported setting it only as a constant.)

New in ColdFusion MX: the pageEncoding attribute is new.

Attributes

Attribute | Req/Opt | Default | Description
suppressWhiteSpace | Optional |  | Boolean. Whether to suppress white space and other output that is generated by CFML tags within a cfprocessingdirective block.
pageEncoding | Optional |  | A string literal; the character encoding to use to read the page. The value may be enclosed in single or double quotation marks, or none.

Usage

If you use the pageEncoding attribute, the following rules apply:

  • You must put the tag within the first 4096 bytes of a page. It can be positioned after a cfsetting or cfsilent tag.
  • If there are multiple occurrences of the tag in one page with the pageEncoding attribute, the attribute must specify the same value; if not, ColdFusion throws an error.
  • You cannot embed the tag within conditional logic, because the tag is evaluated when ColdFusion compiles a page (not when it executes the page). For example, the following code has no effect at execution time, because the cfprocessingdirective tag has already been evaluated:
    • <cfif dynEncoding is not "dynamic encoding is not possible">
   <cfprocessingdirective pageencoding=#dynEncoding#>
</cfif>

You can specify the suppresswhitespace attribute value as a constant or a variable. To use a variable: define the variable (for example, whitespaceSetting), assign it the value "Yes" or "No", and code a statement such as the following:

<!--- ColdFusion allows suppression option to be set at runtime --->

<cfprocessingdirective suppresswhitespace=#whitespaceSetting#>
    code to whose output the setting is applied
</cfprocessingdirective>

This tag’s options do not apply to pages that are included by cfinclude, cfmodule, custom tag invocation, and so on.

Macromedia recommends that you include either the pageencoding or suppresswhitespace attribute; not both.

If you specify only the pageencoding attribute, you must code it within the tag (do not use a separate end tag).

If you specify the suppresswhitespace attribute, you must code it within the start tag, and use and end tag (</cfprocessingdirective).

When the ColdFusion compiler begins processing a page, it searches for a byte order mark (BOM). Processing is as follows:

  • If a BOM is present, ColdFusion uses the encoding that it specifies to read and parse the page.
  • If no BOM is present, ColdFusion uses the system default encoding to read and parse the page.

ColdFusion accepts character encoding names that are defined by the Java platform. If an invalid name is specified, ColdFusion throws an InvalidEncodingSpecification exception.

The following example shows the use of a nested cfprocessingdirective tag. The outer tag suppresses unnecessary whitespace during computation of a large table; the inner tag retains whitespace, to output a preformatted table.

Example

<cfprocessingdirective suppressWhiteSpace = "Yes">
   <!--- CFML code --->
   <cfprocessingdirective suppressWhiteSpace = "No">
      <cfoutput>#table_data#
      </cfoutput>
   </cfprocessingdirective>
</cfprocessingdirective>

The following example shows the use of the pageencoding attribute:

<cfprocessingdirective pageencoding = "shift-jis">


cfprocparam

Description

Parameter information. This tag is nested within a cfstoredproc tag.

Category

Database manipulation tags

Syntax

<cfprocparam
   type = "in" or "out" or "inout"
   variable = "variable name"
   dbVarName = "DB variable name"
   value = "parameter value"
   CFSQLType = "parameter datatype"
   maxLength = "length"
   scale = "decimal places"
   null = "Yes" or "No">

See also

cfinsert , cfprocresult , cfquery , cfqueryparam , cfstoredproc , cftransaction , cfupdate

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
in
  • in: passes the parameter by value.
  • out: passes parameter as bound variable
  • inout: passes parameter as a bound variable
variable
Required if type = "OUT" or "INOUT"
ColdFusion variable name; references the value that the output parameter has after the stored procedure is called.
dbVarName
Required for named notation
Parameter name that corresponds to the name of the parameter in the stored procedure.
value
Required if type = "OUT" or "INOUT"
Value that corresponds to the value that ColdFusion passes to the stored procedure.
CFSQLType
Required
  • SQL type to which the parameter (any type) is bound:
  • CF_SQL_BIGINT
  • CF_SQL_BIT
  • CF_SQL_BLOB
  • CF_SQL_CHAR
  • CF_SQL_CLOB
  • CF_SQL_DATE
  • CF_SQL_DECIMAL
  • CF_SQL_DOUBLE
  • CF_SQL_FLOAT
  • CF_SQL_IDSTAMP
  • CF_SQL_INTEGER
  • CF_SQL_LONGVARCHAR
  • CF_SQL_MONEY
  • CF_SQL_MONEY4
  • CF_SQL_NUMERIC
  • CF_SQL_REAL
  • CF_SQL_REFCURSOR
  • CF_SQL_SMALLINT
  • CF_SQL_TIME
  • CF_SQL_TIMESTAMP
  • CF_SQL_TINYINT
  • CF_SQL_VARCHAR
maxLength
Optional
0
Maximum length of parameter.
scale
Optional
0
Number of decimal places in parameter.
null
Optional
No
Whether parameter is passed as a null value.
  • Yes: tag ignores the value attribute
  • No

Usage

Use this tag to identify stored procedure parameters and their data types. Code one cfprocparam tag for each parameter. The parameters that you code vary based on parameter type and DBMS. The order in which you code cfprocparam tags depends on whether the stored procedure uses positional or named notation:

  • Positional notation: ColdFusion passes parameters to the stored procedure in the order in which they are defined
  • Named notation: The dbVarName for the parameter must correspond to the variable name in the stored procedure on the server

Output variables are scoped with the name of the variable attribute passed to the tag.

CFML supports Oracle 8 Reference Cursor type, which passes a parameter by reference. Parameters that are passed this way can be allocated and deallocated from memory within the execution of one application.

To use reference cursors in packages or stored procedures, use the cfprocresult tag. This causes Datadirect JDBC to put Oracle reference cursors into a result set. (You cannot use this method with Oracle's ThinClient JDBC drivers.)

Example

The following example shows how to invoke an Oracle 8 PL/SQL stored procedure. It makes use of Oracle 8 support of the Reference Cursor type.

The following package, Foo_Data, houses a procedure refcurproc that declares output parameters as Reference Cursor:

  • Parameter pParam1 returns the rows in the EMP table
  • Parameter pParam2 returns the rows in the DEPT table

The procedure declares one input parameter as an integer, and one output parameter as a two-byte char varying type. Before the cfstoredproc tag can call this procedure, it must be created, compiled, and bound in the RDBMS environment.

CREATE OR REPLACE PACKAGE Foo_Data AS
    TYPE EmpTyp IS REF CURSOR RETURN Emp%ROWTYPE;
    TYPE DeptTyp IS REF CURSOR RETURN Dept%ROWTYPE;
 PROCEDURE refcurproc(pParam1 in out EmpTyp, pParam2 in out DeptTyp,
pParam3 in integer, pParam4 out varchar2);
END foo_data;

CREATE OR REPLACE PACKAGE BODY Foo_Data AS
   PROCEDURE RefCurProc(pParam1 in out EmpTyp,
         pParam2 in out DeptTyp,
         pParam3 in integer,
         pParam4 out varchar2) IS
   BEGIN
      OPEN pParam1 FOR select * from emp;
      OPEN pParam2 FOR select * from dept;
      IF pParam3 = 1
      THEN
         pParam4 : = 'hello';
      ELSE
         pParam4 : = 'goodbye';
      END IF;
   END RefCurProc;
END Foo_Data;

The following CFML example shows how to invoke the RefCurProc procedure using cfstoredproc, cfprocparam, and cfprocresult.

<cfstoredproc    procedure = "foo_data.refcurproc"
   dataSource = "oracle8i"
   username = "scott"
   password = "tiger"
   returnCode = "No">

   <cfprocparam type = "Out" CFSQLType = "CF_SQL_REFCURSOR"
      variable = "param1">
   <cfprocparam type = "Out" CFSQLType = "CF_SQL_REFCURSOR"
      variable = "param2">
   <cfprocparam type = "IN" CFSQLType = "CF_SQL_INTEGER" value = "1">

   <cfprocparam type = "OUT" CFSQLType = "CF_SQL_VARCHAR"
      variable = "FOO">

   <cfprocresult name = "rs1">
   <cfprocresult name = "rs2" resultSet = "2">
</cfstoredproc>

<b>The first result set:</b><br>
<hr>
<cftable query = "rs1" colHeaders HTMLTable border = "1">
   <cfcol header = "EMPNO" text = "#EMPNO#">
   <cfcol header = "EMPLOYEE name" text = "#ENAME#">
   <cfcol header = "JOB" text = "#JOB#">
   <cfcol header = "SALARY" text = "#SAL#">
   <cfcol header = "DEPT NUMBER" text = "#DEPTNO#">
</cftable>

<hr>
<b>The second result set:</b><br>

<cftable query = "rs2" colHeaders HTMLTable border = "1">
   <cfcol header = "DEPT name" text = "#DNAME#">
   <cfcol header = "DEPT NUMBER" text = "#DEPTNO#">
</cftable>
<hr>
<cfoutput>
   <b>The output parameter is:</b>'#FOO#'
</cfoutput>


cfprocresult

Description

Result set name that other ColdFusion tags, such as cfoutput and cftable, use to access a result set. Identifies which of the stored procedure’s result sets to return. This tag is nested within a cfstoredproc tag.

Category

Database manipulation tags

Syntax

<cfprocresult
   name = "query_name"
   resultSet = "1-n"
   maxRows = "maxrows">

See also

cfinsert , cfprocparam , cfquery , cfqueryparam , cfstoredproc , cftransaction , cfupdate

Attributes

Attribute | Req/Opt | Default | Description
name | Required |  | Name for the query result set.
resultSet | Optional | 1 | Names one result set, if stored procedure returns more than one.
maxRows | Optional | -1 (All) | Maximum number of rows returned in result set.

Usage

To enable access to data returned by the stored procedure, specify one or more cfprocresult tags.

The resultSet attribute must be unique within the scope of the cfstoredproc tag. If you specify a result set twice, the second occurrence overwrites the first.

Example

<!--- This example executes a Sybase stored procedure that returns three
result sets, two of which we want. The stored procedure returns
status code and one output parameter, which we display. We use
named notation for parameters. --->
<!--- cfstoredproc tag --->
<cfstoredproc procedure = "foo_proc"
      dataSource = "MY_SYBASE_TEST"    username = "sa"
      password = ""    dbServer = "scup"    dbName = "pubs2"
      returnCode = "Yes"    debug = "Yes">
   <!--- cfprocresult tags --->
   <cfprocresult name = RS1>
   <cfprocresult name = RS3 resultSet = 3>
   <!--- cfprocparam tags --->
   <cfprocparam type = "IN"
      CFSQLType = CF_SQL_INTEGER
         value = "1"    dbVarName = @param1>

   <cfprocparam type = "OUT"    CFSQLType = CF_SQL_DATE
      variable = FOO dbVarName = @param2>
   <!--- Close the cfstoredproc tag --->
</cfstoredproc>
<cfoutput>
   The output param value: ’#foo#’<br>
</cfoutput>
<h3>The Results Information</h3>
<cfoutput query = RS1>#name#,#DATE_COL#<br>
</cfoutput>
<p>
<cfoutput>
   <hr>
   <p>Record Count: #RS1.recordCount# <p>Columns: #RS1.columnList#
   <hr>
</cfoutput>
<cfoutput query = RS3>#col1#,#col2#,#col3#<br>
</cfoutput>
<p>
<cfoutput>
   <hr>
   <p>Record Count: #RS3.recordCount# <p>Columns: #RS3.columnList#
   <hr>
   The return code for the stored procedure is:
’#cfstoredproc.statusCode#’<br>
</cfoutput>
...


cfproperty

Description

Defines components as complex types that are used for web services authoring. The attributes of this tag are exposed as component metadata and are subject to inheritance rules.

Category

Extensibility tags

Syntax

<cfproperty
   name=”name”
   type=”type”
   ...>

See also

cfargument , cfcomponent , cffunction , cfinvoke , cfinvokeargument , cfobject , cfreturn

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
A string; a property name. Must be a static value.
type
Optional
A string; a property type name; data type.
  • any
  • array
  • binary
  • boolean
  • date
  • guid
  • numeric
  • query
  • string
  • struct
  • uuid
  • variableName
  • a component name
If the value is not a recognized type, ColdFusion processes it as a component name

Usage

You must position cfproperty tags at the beginning of a component, above executable code and function definitions.

If at least one cfproperty tag that has a property within it is present within a component, the property metadata is present in the component metadata.


cfquery

Description

Passes queries or SQL statements to a data source.

Macromedia recommends that you use the cfqueryparam tag within every cfquery tag, to help secure your databases from unauthorized users. For more information, see:

  • Security Bulletin ASB99-04, "Multiple SQL Statements in Dynamic Queries," at
  • Developing ColdFusion MX Applications with CFML

Category

Database manipulation tags

Syntax

<cfquery
   name = "query_name"
   dataSource = "ds_name"
   dbtype = "query"
   username = "username"
   password = "password"
   maxRows = "number"
   blockFactor = "blocksize"
   timeout = "seconds"
   cachedAfter = "date"
   cachedWithin = "timespan"

   Either of the following:
      debug = "Yes" or "No"
   or:
      debug

   SQL statement(s) >
</cfquery>

See also

cfinsert , cfprocparam , cfprocresult , cfqueryparam , cfstoredproc , cftransaction , cfupdate

History

New in ColdFusion MX: ColdFusion can index query results and delete index keys.

New in ColdFusion MX: Query of Queries supports a subset of standard SQL. For more information, see Developing ColdFusion MX Applications with CFML.

New in ColdFusion MX: ColdFusion supports dot notation within a record set name. ColdFusion interprets such a name as a structure. For more information, see Developing ColdFusion MX Applications with CFML.

New in ColdFusion MX: The connectString, dbName, dbServer, provider, providerDSN, and sql attributes, and all values of the dbtype attribute except query, are deprecated. Do not use them. They do not work, and might cause an error, in releases later than ColdFusion 5.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of query. Used in page to reference query record set. Must begin with a letter. Can include letters, numbers, and underscores.
dataSource
Required
Name of data source from which query gets data.
dbtype
Optional
query
query. Use this value to specify the results of a query as input.
username
Optional
Overrides username in data source setup.
password
Optional
Overrides password in data source setup.
maxRows
Optional
-1 (All)
Maximum number of rows to return in record set.
blockFactor
Optional
1
Maximum rows to get at a time from server. Range: 1 - 100. Applies to ORACLE native database drivers.
timeout
Maximum number of seconds that each action of a query is permitted to execute before returning an error. The cumulative time may exceed this value.
For JDBC statements, ColdFusion sets this attribute. For other drivers, check driver documentation.
cachedAfter
Optional
Date value (for example, April 16, 1999, 4-16-99). If date of original query is after this date, ColdFusion uses cached query data. Takes effect only if query caching is enabled in Administrator. To use cached data, current query must use same SQL statement, data source, query name, user name, password.
A date/time object is in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
When specifying a date value as a string, you must enclose it in quotation marks.
cachedWithin
Optional
Timespan, using the CreateTimeSpan function. If original query date falls within the time span, cached query data is used. CreateTimeSpan defines a period from the present, back. Takes effect only if query caching is enabled in the Administrator.
To use cached data, the current query must use the same SQL statement, data source, query name, user name, and password.
debug
Optional; value and equals sign may be omitted
  • Yes, or if omitted: If debugging is enabled, but the Administrator Database Activity option is not enabled, displays SQL submitted to datasource and number of records returned by query
  • No: If the Administrator Database Activity option is enabled, suppresses display

Usage

Because the timeout parameter only the maximum time for each sub-operation of a query, the cumulative time may exceed its value. To set a timeout for a page that might get a very large result set, set the Administrator > Server Settings > Timeout Requests option to an appropriate value.

This tag returns data and query information from a ColdFusion data source. The cumulative query execution time, in seconds, is returned in the variable cfquery.ExecutionTime.

This tag creates a query object, providing this information in query variables:

Variable name | Description
query_name.currentRow | Current row of query that cfoutput is processing
query_name.columnList | Comma-delimited list of the query columns
query_name.RecordCount | Number of records (rows) returned from the query
cfquery.ExecutionTime | Cumulative time required to process the query

You can cache query results and execute stored procedures. For information about this and about displaying cfquery output, see Developing ColdFusion MX Applications with CFML.

You cannot use SQL reserved words as ColdFusion variable or query names.

Database query results for date and time values can vary in sequence and formatting, unless you use functions to format the results. To ensure that customers using your ColdFusion application are not confused by the display, Macromedia recommends that you use the DateFormat and TimeFormat functions to format values from queries. For more information and examples, see TechNote 22183, "ColdFusion Server (5 and 4.5.x) with Oracle: Formatting Date and Time Query Results," at .

Example

<!--- This example shows the use of CreateTimeSpan with CFQUERY ------>
<!--- define startrow and maxrows to facilitate 'next N' style browsing ---->
<cfparam name="MaxRows" default="10">
<cfparam name="StartRow" default="1">
<!--------------------------------------------------------------------
Query database for information if cached database information has
not been updated in the last six hours; otherwise, use cached data.
--------------------------------------------------------------------->
<cfquery
   name="GetParks" datasource="cfsnippets"
   cachedwithin="#CreateTimeSpan(0, 0, 6, 0)#">
   SELECT PARKNAME, REGION, STATE
   FROM Parks
   ORDER BY ParkName, State
</cfquery>
<!---- build HTML table to display query ------------------------->
<table cellpadding="1" cellspacing="1">
   <tr>
      <td colspan="2" bgcolor="f0f0f0">
         <b><i>Park Name</i></b>
      </td>
      <td bgcolor="f0f0f0">
         <b><i>Region</i></b>
      </td>
      <td bgcolor="f0f0f0">
         <b><i>State</i></b>
      </td>
   </tr>
   <!---- Output the query and define the startrow and maxrows parameters.
      Use the query variable CurrentCount to keep track of the row you
      are displaying. ------>
   <cfoutput
      query="GetParks" startrow="#StartRow#" maxrows="#MaxRows#">
   <tr>
      <td valign="top" bgcolor="ffffed">
         <b>#GetParks.CurrentRow#</b>
      </td>
      <td valign="top">
         <font size="-1">#ParkName#</font>
      </td>
      <td valign="top">
         <font size="-1">#Region#</font>
      </td>
      <td valign="top">
         <font size="-1">#State#</font>
      </td>
   </tr>
   </cfoutput>
   <!----- If the total number of records is less than or equal
   to the total number of rows, then offer a link to
   the same page, with the startrow value incremented by
   maxrows (in the case of this example, incremented by 10) --------->
   <tr>
      <td colspan="4">
      <cfif (StartRow + MaxRows) LTE GetParks.RecordCount>
         <a href="index.cfm?startrow=
            <cfoutput>               #Evaluate(StartRow + MaxRows)#            </cfoutput>
            ">See next <cfoutput>#MaxRows#</cfoutput> rows</a>
      </cfif>
      </td>
   </tr>
</table>


cfqueryparam

Description

Checks the data type of a query parameter. This tag is nested within a cfquery tag, embedded in a query SQL statement. If you specify optional parameters, this tag performs data validation.

Macromedia recommends that you use the cfqueryparam tag within every cfquery tag, to help secure your databases from unauthorized users. For more information, see:

  • Security Bulletin ASB99-04, "Multiple SQL Statements in Dynamic Queries," at
    http://www.allaire.com/handlers/index.cfm?ID=8728&Method=Full
  • Developing ColdFusion MX Applications with CFML

Category

Database manipulation tags

Syntax

<cfquery
   name = "query_name"
   dataSource = "ds_name"
   ...other attributes...
   SELECT STATEMENT WHERE column_name =
   <cfqueryparam value = "parameter value"
      CFSQLType = "parameter type"
      maxLength = "maximum parameter length"
      scale = "number of decimal places"
      null = "Yes" or "No"
      list = "Yes" or "No"
      separator = "separator character">
   AND/OR ...additional criteria of the WHERE clause...
   </cfquery>

See also

cfinsert , cfprocparam , cfprocresult , cfquery , cfstoredproc , cftransaction , cfupdate

Attributes

Attribute
Req/Opt
Default
Description
value
Required
Value that ColdFusion passes to the right of the comparison operator in a where clause.
If CFSQLType is a date or time option:
  • With a native database driver, you cannot specify the #now()# function in this attribute. (Use the DateFormat or TimeFormat function.)
  • With an ODBC driver, you can specify the #now()# function in this attribute.
CFSQLType
Optional
CF_SQL_CHAR
SQL type that parameter (any type) is bound to.
  • CF_SQL_BIGINT
  • CF_SQL_BIT
  • CF_SQL_CHAR
  • CF_SQL_BLOB
  • CF_SQL_CLOB
  • CF_SQL_DATE
  • CF_SQL_DECIMAL
  • CF_SQL_DOUBLE
  • CF_SQL_FLOAT
  • CF_SQL_IDSTAMP
  • CF_SQL_INTEGER
  • CF_SQL_LONGVARCHAR
  • CF_SQL_MONEY
  • CF_SQL_MONEY4
  • CF_SQL_NUMERIC
  • CF_SQL_REAL
  • CF_SQL_REFCURSOR
  • CF_SQL_SMALLINT
  • CF_SQL_TIME
  • CF_SQL_TIMESTAMP
  • CF_SQL_TINYINT
  • CF_SQL_VARCHAR
maxLength
Optional
Length of string in value attribute
Maximum length of parameter.
scale
Optional
0
Number of decimal places in parameter. Applies to CF_SQL_NUMERIC and CF_SQL_DECIMAL.
null
Optional
No
Whether parameter is passed as a null value.
  • Yes: tag ignores the value attribute
  • No
list
Optional
No
  • Yes: The value attribute value is a delimited list
  • No
separator
Required, if you specify a list in value attribute
, (comma)
Character that separates values in list, in value attribute.

Usage

For data, to ensure that validation is enforced, you must specify the maxlength attribute.

This tag does the following:

  • Allows the use of SQL bind parameters
  • Allows long text fields to be updated from an SQL statement
  • Improves performance

The ColdFusion ODBC, DB2, Informix, Oracle 7 and Oracle 8 drivers support SQL bind parameters. The ColdFusion Sybase 11 driver and Sybase native driver do not support SQL bind parameters.

If a database does not support bind parameters, ColdFusion validates and substitutes the validated parameter value back into the string. If validation fails, it returns an error message.

The validation rules are as follows:

  • For these types, a data value can be converted to a numeric value: CF_SQL_SMALLINT, CF_SQL_INTEGER, CF_SQL_REAL, CF_SQL_FLOAT, CF_SQL_DOUBLE, CF_SQL_TINYINT, CF_SQL_MONEY, CF_SQL_MONEY4, CF_SQL_DECIMAL, CF_SQL_NUMERIC, and CF_SQL_BIGINT
  • For these types, a data value can be converted to a date supported by the target data source: CF_SQL_DATE, CF_SQL_TIME, CF_SQL_TIMESTAMP
  • For all other types, if the maxLength attribute is used, a data value cannot exceed the maximum length specified.

The SQL syntax that the ColdFusion server generates depends on the target database. For an ODBC, DB2, or Informix data source, the syntax is as follows:

SELECT *
   FROM courses
   WHERE col1 = ?

For an Oracle 7 or Oracle 8 data source, the syntax is as follows:

SELECT *
   FROM courses
   WHERE col1 = :1

For a Sybase11 data source, the syntax is as follows:

SELECT *
   FROM courses
   WHERE col1 = 10

Example

<!--- This example shows cfqueryparam with VALID input in Course_ID. --->
<h3>cfqueryparam Example</h3>
<cfset Course_ID = 12>
<cfquery name = "getFirst" dataSource = "cfsnippets">
   SELECT *
   FROM courses
   WHERE Course_ID = <cfqueryPARAM value = "#Course_ID#"
   CFSQLType = "CF_SQL_INTEGER">
</cfquery>
<cfoutput query = "getFirst">
   <p>Course Number: #Course_ID#<br> Description: #descript#</p>
</cfoutput>

<!--- This example shows the use of CFQUERYPARAM when INVALID string data is
   in Course_ID. ---->
<p>This example throws an error because the value passed in the CFQUERYPARAM
tag exceeds the MAXLENGTH attribute</p>

<cfset LastName="Peterson; DELETE employees WHERE LastName='Peterson'">
<!------- Note that for string input you must specify the MAXLENGTH attribute
   for validation. -------------------------------------------------->
<cfquery
   name="getFirst" datasource="cfsnippets">
   SELECT *
   FROM employees
   WHERE LastName=<cfqueryparam
                        value="#LastName#"
                        cfsqltype="CF_SQL_VARCHAR"
                        maxlength="17">
</cfquery>
<cfoutput
   query="getFirst">       <p>
      Course Number: #FirstName# #LastName#
      Description: #Department# </p>
</cfoutput>


cfregistry

Description

This tag is deprecated for the UNIX platform.

Reads, writes, and deletes keys and values in the system registry. Provides persistent storage of client variables.

Note: For this tag execute, it must be enabled in the ColdFusion Administrator. For more information, see Administering ColdFusion MX.

Category

Other tags, Variable manipulation tags

Syntax

The tag syntax depends on the action attribute value. See the following sections.

  • cfregistry action = "getAll"
  • cfregistry action = "get"
  • cfregistry action = "set"
  • cfregistry action = "delete"

See also

cfcookie , cfparam , cfsavecontent , cfschedule , cfset

History

New in ColdFusion MX: This tag is deprecated on the UNIX platform. Do not use it in new applications in which ColdFusion Server runs on UNIX. It might not work, and might cause an error, in later releases.

New in ColdFusion MX: The functionality of this tag is available through the web services architecture. ColdFusion stores most persistent data outside the system registry, in XML files.

New in ColdFusion MX: ColdFusion stores most persistent data outside the system registry, in XML files.


cfregistry action = "getAll"

Description

Returns all registry keys and values defined in a branch. You can access the values as you would any record set.

Syntax

<cfregistry
   action = "getAll"
   branch = "branch"
   type = "data type"
   name = "query name"
   sort = "criteria">

Attributes

Attribute
Req/Opt
Default
Description
action
Required
getall
branch
Required
Name of a registry branch.
type
Optional
String
  • string: return string values
  • dWord: return DWord values
  • key: return keys
  • any: return keys and values
name
Required
Name of record set to contain returned keys and values.
sort
Optional
ASC
Sorts query column data (case-insensitive). Sorts on Entry, Type, and Value columns as text. Specify a combination of columns from query output, in a comma-delimited list. For example:
sort = "value desc, entry asc"
  • asc: ascending (a to z) sort order
  • desc: descending (z to a) sort order

Usage

This tag returns #entry#, #type#, and #value# in a record set that you can access through tags such as cfoutput. To fully qualify these variables, use the record set name, as specified in the name attribute.

If #type# is a key, #value# is an empty string.

If you specify type= "any", getAll also returns binary registry values. For binary values, the #type# variable contains UNSUPPORTED and #value# is blank.

Example

<!--- This example uses cfregistry with the getAll Action --->
<cfregistry action = "getAll"
   branch = "HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM"
   type = "Any" name = "RegQuery">
<p><h1>cfregistry action = "getAll"</h1>
<cftable query = "RegQuery" colHeaders HTMLTable border = "Yes">
<cfcol header = "<b>Entry</b>" width = "35" text = "#RegQuery.Entry#">
<cfcol header = "<b>Type</b>" width = "10" text = "#RegQuery.type#">
<cfcol header = "<b>Value</b>" width = "35" text = "#RegQuery.Value#">
</cftable>


cfregistry action = "get"

Description

Accesses a registry value and stores it in a ColdFusion variable.

Syntax

<cfregistry
   action = "get"
   branch = "branch"
   entry = "key or value"
   variable = "variable"
   type = "data type">

Attributes

Attribute
Req/Opt
Default
Description
action
Required
get
branch
Required
Name of a registry branch.
entry
Required
Registry value to access.
variable
Required
Variable into which to put value.
type
Optional
string
  • string: return string value
  • dWord: return DWord value
  • key: return key’s default value

Usage

If the value does not exist, cfregistry does not create an entry.

Example

<!--- This example uses cfregistry with the Get Action --->
<cfregistry action = "get"
 branch = "HKEY_LOCAL_MACHINE\Software\Microsoft\Java VM"
 entry = "ClassPath" type = "String" variable = "RegValue">
<h1>cfregistry action = "get"</h1>
<cfoutput>
   <p>Java ClassPath value is #RegValue#
</cfoutput>


cfregistry action = "set"

Description

Adds a registry key, adds a value, or updates a value.

Syntax

<cfregistry
   action = "set"
   branch = "branch"
   entry = "key or value"
   type = "value type"
   value = "data">

Attributes

Attribute
Req/Opt
Default
Description
action
Required
set
branch
Required
Name of a registry branch.
entry
Required
Key or value to set.
type
Optional
  • string: set a string value (default).
  • dWord: set a DWord value.
  • key: create a key.
value
Optional
Value data to set. If you omit this attribute, cfregistry creates default value, as follows:
  • string: creates an empty string: ""
  • dWord: creates a value of 0 (zero)

Usage

If it does not exist, cfregistry creates the key or value.

Example

<!--- This example uses cfregistry Set Action to modify registry value data --->
<!--- Normally you pass in a file name instead of setting one here. --->
<cfset FileName = "dummy.cfm">
<cfregistry action = "set"
 branch = "HKEY_LOCAL_MACHINE\Software\cflangref"
 entry = "LastCFM01" type = "String" value = "#FileName#">
<h1>cfregistry action = "set"</h1>


cfregistry action = "delete"

Description

Deletes a registry key or value.

Syntax

<cfregistry
   action = "delete"
   branch = "branch"
   entry = "keyorvalue">

Attributes

Attribute
Req/Opt
Default
Description
action
Required
delete
branch
Required
  • For key deletion: name of registry key to delete. Do not specify the entry.
  • For value deletion: name of registry branch that contains value to delete. You must specify entry.
entry
Required for value deletion
Value to delete

Usage

If you delete a key, cfregistry also deletes values and subkeys defined beneath it.

Example

<cfregistry action = "delete"
 branch = "HKEY_LOCAL_MACHINE\Software\cflangref\tempkey"
 entry = "LastCFM01">
<h1>cfregistry action = "delete"</h1>


cfreport

Description

Runs a predefined Crystal Reports report. Applies only to Windows systems. Uses the CFCRYSTAL.exe file to generate reports. Sets parameters in the Crystal Reports engine according to its attribute values.

Category

Extensibility tags

Syntax

<cfreport
   report = "report_path"
   dataSource = "ds_name"
   type = "type"
   timeout = "number of seconds"
   orderBy = "result_order"
   username = "username"
   password = "password"
   formula = "formula">
</cfreport>

See also

cfcollection , cfexecute , cfindex , cfobject , cfsearch , cfwddx

History

New in ColdFusion MX: Crystal Reports establishes an independent connection to the data source. The connection is not subject to any ColdFusion data source-specific restrictions. For example, the Crystal Reports server can access a data source regardless of whether it is disabled in the ColdFusion Administrator.

Attributes

Attribute
Req/Opt
Default
Description
datasource
Optional
Name of registered or native data source
type
Optional
standard
  • standard (not valid for Crystal Reports 8.0)
  • netscape
  • microsoft
timeout
Optional
Maximum time, in seconds, in which a connection must be made to a Crystal Report
report
Required
Report path. Store Crystal Reports files in the same directories as ColdFusion page files.
orderBy
Optional
Orders results according to your specifications.
username
Optional
Username required for entry into database from which report is created. Overrides default settings for data source in ColdFusion Administrator.
password
Optional
Password that corresponds to username required for database access. Overrides default settings for data source in ColdFusion Administrator.
formula
Optional
One or more named formulas. Terminate each formula with a semicolon. Use the format:
formula = "formulaname1 = 'formula1';formulaname2 = 'formula2';"
If you use a semicolon in a formula, you must escape it by typing it twice (;;). For example:
formula = "Name1 = 'Val_1a;;Val_1b';Name2 = 'Val2';"

Usage

This tag requires an end tag.

Example

<!--- This view-only example shows the use of cfreport --->
<h3>cfreport Tag<h3>
<p>cfreport lets reports from the Crystal Reports Professional report writer
display through a ColdFusion interface. To run, the tag requires the
name of the report. cfreport can also pass information to the report
file displayed, to change the output conditions.
<p>This example would run a report called "monthlysales.rpt " and pass it an
optional filter condition to show only the information for a subset
of the report.

<cfreport report = ’/reports/monthlysales.rpt’>
     {Departments.Department} = ‘International’
</cfreport>

<p>Substitute your report files and filters for this code. cfreport can put
Crystal Reports into web pages.


cfrethrow

Description

Rethrows the currently active exception. Preserves the exception’s cfcatch.type and cfcatch.tagContext variable values.

Category

Exception handling tags, Extensibility tags

Syntax

<cfrethrow>

See also

cferror , cfthrow , cftry

Usage

Use this tag within a cfcatch block. This tag is useful in error handling code, if the error handler cannot handle an error that it catches. For example, if cfcatch type = "any" gets a DATABASE exception, and the code is designed to handle only CFX exceptions, the handler raises the exceptions again, with details intact, so that a higher-level handler can process the error information. If you used the cfthrow tag, the type and details of the original exception would be lost.

Example

<h3>cfrethrow Example</h3>
<!--- Rethrow a DATABASE exception. --->
<cftry>
   <cftry>
      <cfquery name = "GetMessages" dataSource = "cfsnippets">
         SELECT  *
         FROM   Messages
      </cfquery>
   <cfcatch type = "DATABASE">
      <!---- If database signalled a 50555 error, ignore; otherwise rethrow
exception. ---->
      <cfif cfcatch.sqlstate neq 50555>
         <cfrethrow>
      </cfif>
   </cfcatch>
   </cftry>
<cfcatch>
   <h3>Sorry, this request can't be completed</h3>
   <h4>Catch variables</h4>
   <cfoutput>
      <cfloop collection = #cfcatch# item = "c">
         <br>
         <cfif IsSimpleValue(cfcatch[c])>#c# = #cfcatch[c]#
         </cfif>
      </cfloop>
   </cfoutput>
</cfcatch>
</cftry>


cfreturn

Description

Returns result values from a component method. Contains an expression returned as result of the function.

Return value

An expression; the result of the function from which this tag is called.

Category

Extensibility tags

Syntax

<cfreturn
   expr>

See also

cfargument , cfcomponent , cffunction , cfinvoke , cfinvokeargument , cfobject , cfproperty

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute | Req/Opt | Default | Description
expr | Required |  | Function result; value of any type

Usage

This tag is equivalent to a return statement within a cfscript tag. It accepts one return variable argument. To return more than one value, populate a structure with name-value-pairs, and return the structure with this tag.

To access the result value from this tag, you use the variable scope that is the value of the cfinvoke tag returnVariable attribute.

You can code a maximum of one cfreturn tag within a function.

For example code, see the Building and Using ColdFusion Components chapter of Developing ColdFusion MX Applications with CFML.

Example

<cfcomponent>
   <cffunction name="getEmp">
       <cfquery name="empQuery" datasource="ExampleApps" >
          SELECT FIRSTNAME, LASTNAME, EMAIL
          FROM tblEmployees
       </cfquery>
       <cfreturn empQuery>
   </cffunction>
   <cffunction name="getDept">
      <cfquery name="deptQuery" datasource="ExampleApps" >
          SELECT *
          FROM tblDepartments
       </cfquery>
       <cfreturn deptQuery>
   </cffunction>
</cfcomponent>


cfsavecontent

Description

Saves the generated content of the cfsavecontent tag, including the results of evaluating expressions and executing custom tags, in the specified variable.

Category

Variable manipulation tags

Syntax

<cfsavecontent
   variable = "variable name">
   the content
</cfsavecontent>

See also

cfcookie , cfparam , cfregistry , cfschedule , cfset

Attributes

Attribute | Req/Opt | Default | Description
variable | Required |  | Name ofthe variable in which to save the generated content of the tag.

Usage

This tag requires an end tag.

You cannot use this tag to suppress output from a tag library.

Example

The following example uses a custom tag to generate a report and saves the report in the variable CONTENT. It replaces all instances of the word "report" with the phrase "MyCompany Quarterly Report" and outputs the result.

<cfsavecontent variable="content">
   <CF_OutputBigReport>
</cfsavecontent>
<cfoutput>
   #replace(content, "report", "MyCompany Quarterly Report", "all")#
</cfoutput>


cfschedule

Description

Provides a programmatic interface to the ColdFusion scheduling engine. You can run a page at scheduled intervals, with the option to write out static HTML pages. This lets users access pages that publish data, such as reports, without waiting while a database transaction is performed to populate the page.

You register ColdFusion scheduled events in the ColdFusion Administrator. You can disable cfschedule execution in the Administrator.

Information that the user supplies includes the scheduled ColdFusion page to execute, the time and frequency of execution, and whether to publish the task output. If the output is published, a path and file are specified.

The event submission and its success or failure status is written to the \cfusion\log\schedule.log file.

Category

Variable manipulation tags

Syntax

<cfschedule
   action = "update"
   task = "taskname"
   operation = "HTTPRequest"
   file = "filename"
   path = "path_to_file"
   startDate = "date"
   startTime = "time"
   url = "URL"
   publish = "Yes" or "No"
   endDate = "date"
   endTime = "time"
   interval = "seconds"
   requestTimeOut = "seconds"
   username = "username"
   password = "password"
   resolveURL = "Yes" or "No"
   proxyServer = "hostname"
   port = "port_number"
   proxyPort = "port_number">

<cfschedule
   action = "delete"
   task = "TaskName">

<cfschedule
   action = "run"
   task = "TaskName">

See also

cfcookie , cfparam , cfregistry , cfsavecontent , cfset

Attributes

Attribute
Req/Opt
Default
Description
action
Required
  • delete: deletes task
  • update: creates task, if one does not exist
  • run: executes task
task
Required
Name of task.
operation
Required if action = "update"
Task that scheduler performs. For static page generation, the only option is "HTTPRequest".
file
Required if publish = "Yes"
Filename for the published file.
path
Required if publish = "Yes"
Path location for the published file.
startDate
Required if action = "update"
Date when task scheduling starts.
startTime
Required if action = "update"
Time when scheduling of task starts (seconds).
url
Required if action = "update"
URL to execute.
publish
Optional
No
  • Yes: save the result to a file
  • No
endDate
Optional
Date when scheduled task ends.
endTime
Optional
Time when scheduled task ends (seconds).
interval
Required if action = "update"
One hour
Interval at which task is scheduled.
  • number of seconds (minimum is 60)
  • once
  • daily
  • weekly
  • monthly
requestTimeOut
Optional
Can be used to extend the default timeout period.
username
Optional
Username, if URL is protected.
password
Optional
Password, if URL is protected.
proxyServer
Optional
Host name or IP address of a proxy server.
resolveURL
Optional
No
  • Yes: resolve links in result page to absolute references
  • No
port
Optional
80
Server port number from which the task is scheduled. IF resolveURL= "yes", retrieved document URLs that specify a port number are automatically resolved, to preserve links in the retrieved document.
proxyPort
Optional
80
Port number on proxy server from which task is requested. When used with resolveURL, URLs of retrieved documents that specify a port number are automatically resolved, to preserve links in retrieved document.

Usage

You cannot use cfschedule and apply Secure Sockets Layer (SSL) to an application.

Example

<h3>cfschedule Example</h3>
<p>cfschedule provides a programmatic interface to the ColdFusion scheduling
engine. You can run a specified page at scheduled intervals with the
option to write out static HTML pages. This lets you offer users access
to pages that publish data, such as reports, without forcing users to
wait while a database transaction is performed to populate the data
on the page.
<p>View-only-example</p>
<cfschedule action = "update"
   task = "TaskName"
   operation = "HTTPRequest"
   url = "http://127.0.0.1/playpen/history.cfm"
   startDate = "8/7/98"
   startTime = "12:25 PM"
   interval = "3600"
   resolveURL = "Yes"
   publish = "Yes"
   file = "sample.html"
   path = "c:\inetpub\wwwroot\playpen"
   requestTimeOut = "600">


cfscript

Description

Encloses a code block that contains cfscript statements.

Category

Application framework tags, Other tags

Syntax

<cfscript>
   cfscript code here
</cfscript>

See also

cfinvoke , cfmodule , CreateObject

History

New in ColdFusion MX:

  • This tag can invoke component methods, using the createObject function
  • You cannot use ColdFusion reserved words within this tag
  • You can use cftry and cfcatch tags as cfscript constructs

Usage

Performs processing in CFScript. This tag uses ColdFusion functions, expressions, and operators. You can read and write ColdFusion variables within this tag.

You can use this tag to enclose a series of assignment statements that would otherwise require cfset statements.

Caution:If you code a cftry/cfcatch block within this tag using an exception’s Java class name, you must provide the fully-qualified class name.

You cannot use some ColdFusion reserved words in this tag. You cannot put a user-defined function whose name begins with any of these strings within this tag:

  • cf
  • cf_
  • _cf
  • coldfusion
  • coldfusion_
  • _coldfusion

You cannot use the elseif construct within a cfscript tag. You can use code such as the following:

else if ( condition )
{
...
}


Exception handling with the cfscript tag

To handle exceptions with this tag, use try and catch statements, which are equivalent to the cftry and cfcatch tags. For each try statement, you must have a catch statement. In the catch block, the variable exceptionVariable contains the exception type. This variable is the equivalent of the cfcatch tag built-in variable cfcatch.Type. For more information, see Developing ColdFusion MX Applications with CFML.


Invoking ColdFusion components with the cfscript tag

CFScript invokes component methods using the createObject function.

The following example shows how to invoke a component object with the cfscript tag, using ordered arguments:

<cfscript>
quote = createObject( “component”, “nasdaq.quote” ) ;
<!--- invocation using ordered arguments --->
res = quote.getLastTradePrice( “macr” ) ;
</cfscript>

The following example shows how to use an attribute collection within the cfscript tag to pass parameters when invoking a component object. An attribute collection is a structure in which each key corresponds to a parameter name and each value is the parameter value passed for the corresponding key.

<cfscript>
   stArgs = structNew();
   stArgs.translationmode = "en_es";
   stArgs.sourceData= "Hello world, friend";
</cfscript>
...
<cfinvoke
   webservice = "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"
   method     = "BabelFish"
   argumentCollection = "#stArgs#"
   returnVariable = "varName"   >
<cfoutput>#varName#</cfoutput>

In this example, the structure is created in a cfscript block, but you can use any ColdFusion method to create the structure.


Consuming web services with the cfscript tag

The following example shows how to consume a web service with the cfscript tag. You use the CreateObject function to connect to the web service.

<cfscript>
   ws = CreateObject("webservice",
            "http://www.xmethods.net/sd/2001/BabelFishService.wsdl");
   xlatstring = ws.BabelFish("en_es", "Hello world, friend");
   writeoutput(xlatstring);
</cfscript>

For more information, see Developing ColdFusion MX Applications with CFML.

Example

<p>This simple example shows variable declaration and manipulation.
<cfif IsDefined("form.myValue")>
   <cfif IsNumeric(form.myValue)>
      <cfset x = form.myValue>
      <cfscript>
         y = x;
         z = 2 * y;
         StringVar = form.myString;
      </cfscript>
   <cfoutput>      <p>twice #x# is #z#.
      <p>Your string value was: <b><I>#StringVar#</i></b>   </cfoutput>
<cfelse>
Previous


ColdFusion Tags: cfsearch--cfxml


cfsearch

Description

Searches Verity collections using ColdFusion or K2Server, whichever search engine a collection is registered by. (ColdFusion can also search collections that have not been registered, with the cfcollection tag.)

A collection must be created and indexed before this tag can return search results.

A collection can be created in these ways:

  • With the cfcollection tag
  • In the ColdFusion Administrator, which calls the cfcollection tag
  • Externally, using a native Verity indexing tool, such as Vspider or MKVDK

A collection can be registered with ColdFusion in the following ways:

  • With the cfcollection tag
  • In the ColdFusion Administrator, which calls the cfcollection tag

A collection can be registered with K2Server by editing the k2server.ini file.

A collection can be indexed in the following ways:

  • In ColdFusion, with the cfindex tag
  • In the ColdFusion Administrator, which calls the cfindex tag
  • Using a native Verity indexing tool, such as Vspider or MKVDK

For more information, see Developing ColdFusion MX Applications with CFML.

Category

Extensibility tags

Syntax

<cfsearch
   name = "search_name"
   collection = "collection_name"
   type = "criteria"
   criteria = "search_expression"
   maxRows = "number"
   startRow = "row_number"
   language = "language">

See also

cfcollection , cfexecute , cfindex , cfobject , cfreport , cfwddx

History

New in ColdFusion MX: the The external attribute is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases. (ColdFusion stores this information about each collection; it automatically detects whether a collection is internal or external.) This tag supports absolute (also known as fully qualified) collection pathnames and mapped collection names.

New in ColdFusion MX: ColdFusion can create collections, index query results and delete index keys.

New in ColdFusion MX: ColdFusion supports Verity operations on Acrobat PDF files.

New in ColdFusion MX: This tag can search multiple collections. In a multiple collection search, you cannot combine collections that are registered with K2Server and and registered in another way.

New in ColdFusion MX: This tag accepts collection names that include spaces.

New in ColdFusion MX: this tag supports Verity 2.6.1 and the LinguistX and ICU locales.

New in ColdFusion MX: This tag can throw the SEARCHENGINE exception.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of the search query.
collection
Required
One or more path(s) and/or registered collection name(s).
For a registered collection, specify the collection name.
For an unregistered collection, specify an absolute path.
Registered names are listed in the ColdFusion Administrator, Verity Collections and Verity Server pages.
To specify multiple collections, use a comma delimiter. For example: "CFUSER, e:\collections\personnel
If you specify multiple collections, you cannot include a combination of collections that are registered by K2Server and registered by Verity.
type
Optional
simple
  • simple: STEM and MANY operators are implicitly used. See Developing ColdFusion MX Applications with CFML.
  • explicit: operators must be invoked explicitly
criteria
Optional
Search criteria. Follows the syntax rules of the type attribute. If you pass a mixed-case entry in this attribute, the search is case-sensitive. If you pass all uppercase or all lowercase, the search is case-insensitive. Follow Verity syntax and delimiter character rules; see Developing ColdFusion MX Applications with CFML.
maxRows
Optional
All
Maximum number of rows to return in query results. Use double or single quotation marks.
startRow
Optional
1
First row number to get.
language
Optional
english
For options, see cfcollection. Requires the ColdFusion International Search Pack.

Usage

To permit application users to search Verity collections for non-standard strings, words or characters (for example, "AB23.45.67" or "--->") that would otherwise cause an error, you can create a text file that lists these elements and defines their formats for Verity. Name the file style.lex and put copies of the file in these directories:

  • Windows:
    • cf_root\lib\common\style (typically, cf_root = c:\cfusionmx)
    • cf_root\lib\common\style\custom
    • cf_root\lib\common\style\file
  • Unix:
    • cf_root/lib/common/style (typically, cf_root = /opt/coldfusionmx)
    • cf_root/lib/common/style/custom
    • cf_root/lib/common/style/file

Note: To search for a character such as an angle bracket (< or >), you must use a criteria attribute value such as "&lt:" or "&lt:". The bracket characters are reserved in Verity, and using a backslash to escape the character (criteria="\<") does not work in this context. For more information, see Developing ColdFusion MX Applications with CFML.

Macromedia does not recommend using the cflock tag with this tag; Verity provides the locking function. Using the cflock tag slows search performance.

This tag returns a record set whose columns you can reference in a cfoutput tag. For example, the following code specifies a search for the exact terms "filming" or "filmed":

<cfsearch
name = "mySearch"
collection = "myCollection"
criteria = '<WILDCARD>`film{ing,ed}`'
type="explicit"
startrow=1>
<cfdump var = "#mySearch#>

In this example, the single quotation mark (') and backtick (`) characters are used as delimiters; for more information, see Developing ColdFusion MX Applications with CFML.

Next


cfsearch result columns

Variable | Description
url | Value of URLpath attribute in the cfindex tag used to populate a collection. If type = "custom", the value is always empty when you populate a collection.
key | Value of the attribute in the cfindex tag used to populate collection
title | Value of title attribute in cfindex operation used to populate the collection, including PDF and Office document titles. If title is not provided, the tag uses the cfindex title attribute value for each row.
score | Relevancy score of document based on search criteria
custom1, custom2 | Value of custom fields in cfindex operation used to populate collection.
summary | Contents of automatic summary generated by cfindex. Default: best three matching sentences, up to 500 characters.
recordCount | Number of records returned in record set
currentRow | Current row that cfoutput is processing
columnList | List of column names within record set
recordsSearched | Number of records searched

You can use query result columns in standard CFML expressions, preceding the result column name with the name of the query, as follows:

#DocSearch.url#
#DocSearch.key#
#DocSearch.title#
#DocSearch.score#

Example

<!--- #1 (TYPE=SIMPLE) ----------------------------->
<cfsearch
      name="name"
      collection="snippets,syntax,snippets"
      criteria="example" >
<p>
<cfoutput>Search Result total =  #name.RecordCount# </cfoutput><br>
<cfoutput>
      url=#name.url#<br>
      key=#name.key#<br>
      title=#name.title#<br>
      score=#name.score#<br>
      custom1=#name.custom1#<br>
      custom2=#name.custom2#<br>
      summary=#name.summary#<br>
      recordcount=#name.recordcount#<br>
      currentrow=#name.currentrow#<br>
      columnlist=#name.columnlist#<br>
      recordssearched=#name.recordssearched#<br>
</cfoutput>
<cfdump var = #name#>
<br>

<!--- #2 (TYPE=EXPLICIT) ----------------------------->
<cfsearch
      name = "snippets"
      collection = "snippets"
      criteria = '<wildcard>`film{ing,ed}`'
      type="explicit"
      startrow=1>
<cfoutput
      query="snippets">
      url=#url#<br>
      key=#key#<br>
      title=#title#<br>
      score=#score#<br>
      custom1=#custom1#<br>
      custom2=#custom2#<br>
      summary=#summary#<br>
      recordcount=#recordcount#<br>
      currentrow=#currentrow#<br>
      columnlist=#columnlist#<br>
      recordssearched=#recordssearched#<br>
</cfoutput>
<cfdump var = #snippets#>
<br>

<!--- #3 (search by CF key) ----------------------------->
<cfsearch
      name = "book"
      collection = "custom_book"
      criteria = "cf_key=bookid2">
<cfoutput>
      url=#book.url#<br>
      key=#book.key#<br>
      title=#book.titleE#<br>
      score=#book.score#<br>
      custom1=#book.custom1#<br>
      custom2=#book.custom2#<br>
      summary=#book.summary#<br>
      recordcount=#book.recordcount#<br>
      currentrow=#book.currentrow#<br>
      columnlist=#book.columnlist#<br>
      recordssearched=#book.recordssearched#<br>
</cfoutput>
<cfdump var = #book#>
<br>


cfselect

Description

Constructs a drop-down list box form control. Used within a cfform tag.

You can populate the list from a query, or by using the HTML option tag.

Category

Forms tags

Syntax

<cfselect
   name = "name"
   required = "Yes" or "No"
   message = "text"
   onError = "text"
   size = "integer"
   multiple = "Yes" or "No"
   query = "queryname"
   selected = "column_value"
   value = "text"
   display = "text"
   passThrough = "HTML_attributes">
</cfselect>

See also

cfapplet , cfform , cfgrid , cfinput , cfgridcolumn , cfgridrow , cfgridupdate , cfslider , cftextinput , cftree , cftreeitem

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name of the select form element
size
Optional
Number of entries in drop-down list.
required
Optional
No
  • Yes: a list element must be selected when form is submitted. Minimum size of select box is 2.
  • No
message
Optional
Message to display if required = "Yes" and no selection is made.
onError
Optional
Custom JavaScript function to execute if validation fails
multiple
Optional
No
  • Yes: allow selecting multiple elements in drop-down list
  • No
query
Optional
Name of query to populate drop-down list.
selected
Optional
A list of option values to preselect in the selection list. This attribute applies only if list items are generated from a query. The cfform preservedata attribute value can override this value.
value
Optional
Query column to use for the value of each list element. Used with query attribute.
display
Optional
Value of value attribute
Query column to use for the display label of each list element. Used with query attribute.
passThrough
Optional
HTML attribute(s) that are not explicitly supported by cfselect. If you specify an attribute and its value, they are passed to HTML code that is generated for cfselect tag.
For example:
"style=""font-family:courier"""

Usage

To ensure that a selected list box item persists across postbacks, use the cfform preserveData attribute with a list generated from a query. (This strategy works only with data that is populated from a query.)

If the cfform preserveData attribute is true and the form posts back to the same page, and if the control is populated by a query, the posted selection(s) for the cfselect control are used instead of the Selected attribute. For controls that are populated with regular HTML option tags, the developer must dynamically add the Selected attribute to the appropriate option tag(s).

For this tag to work properly. the browser must be JavaScript-enabled.

To add other HTML <input> tag attributes and values to this tag, use the passThrough attribute. They are passed through to the select tag that ColdFusion generates for the cfselect control when creating a form. The supported HTML attributes are: CLASS, ID, MAXLENGTH, MESSAGE, ONBLUR, ONCHANGE, ONCLICK, ONDBLCLICK, ONFOCUS, SIZE, STYLE, and TABINDEX.

If you put a value in quotation marks, you must escape them; for example:

passThrough = "readonly = " "yes " " "

For more information, see the cfform tag entry.

This tag requires an end tag.

Example

<!--- This example shows the use of cftree, cfselect and cfgrid in a cfform.
The query takes a list of employees, and uses cftree and cfselect to
display results of query. cfgrid is used to show an alternate means
of displaying the data --->
<!--- set a default for the employeeNames variable --->
<cfparam name = "employeeNames" default = "">
<!--- if an employee name has been passed from the form, set employeeNames
variable to this value --->
<cfif IsDefined("form.employeeNames") is not "False">
   <cfset employeeNames = form.employeeNames>
</cfif>

<!--- query the datasource to find the employee information--->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
   SELECT  Emp_ID, FirstName, LastName, EMail, Phone, Department
   FROM   Employees
   WHERE 0=0
      <cfif employeeNames is not "">
         AND LastName = '#employeeNames#'
      </cfif>
</cfquery>

<h3>cfselect Example</h3>
<!--- Use cfform when using other cfinput tools --->
<cfform action = "cfselect.cfm">

<!--- Use cfselect to present the contents of the query by column --->
<h3>cfselect Presentation of Data</h3>
<h4>Click on an employee’s last name and hit "see information for this employee"
   to see expanded information.</h4>
<cfselect name = "EmployeeNames"
   message = "Select an Employee Name"
size = "#getEmployees.recordcount#"
query = "GetEmployees" value = "LastName"
required = "No">
<option value = "">Select All
</cfselect>

<input type="Submit"
   name="" value="see information for this employee">
<!--- showing the use of cftree ------------------------------------------>
<!--- use cftree for an expanded presentation of the data Loop through the
      query to create each branch of the CFTREE ----------------------------->
<h3>cftree Presentation of Data</h3>
<h4>Click on the folders to "drill down" and reveal information.</h4> <p>
   <cftree name="SeeEmployees"
      height="150" width="240" font="Arial Narrow" bold="No"
      italic="No" border="Yes" hscroll="Yes" vscroll="Yes"
      required="No" completepath="No" appendkey="Yes" highlighthref="Yes">
   <cfloop query="GetEmployees">
      <cftreeitem value="#Emp_ID#" parent="SeeEmployees" expand="No">
      <cftreeitem value="#LastName#" display="Name" parent="#Emp_ID#"
         queryasroot="No" expand="No">
      <cftreeitem value="#LastName#, #FirstName#" parent="#LastName#"
         expand="No" queryasroot="No">
      <cftreeitem value="#Department#" display="Department" parent="#Emp_ID#"
         queryasroot="No" expand="No">
      <cftreeitem value="#Department#" parent="#Department#"
         expand="No" queryasroot="No">
      <cftreeitem value="#Phone#" display="Phone" parent="#Emp_ID#"
         queryasroot="No" expand="No">
      <cftreeitem value="#Phone#" parent="#Phone#"
         expand="No" queryasroot="No">
      <cftreeitem value="#Email#" display="Email" parent="#Emp_ID#"
         queryasroot="No" expand="No">
      <cftreeitem value="#Email#" parent="#Email#"
         expand="No" queryasroot="No">
   </cfloop>
</cftree>
<!----- You can also use CFGRID for a more comprehensive, quicker view at
   the data ---------------------------------------------------------------->
<h3>CFGRID Presentation of Data</h3>
<cfgrid name="SampleGrid"
   width="600" query="GetEmployees" insert="No" delete="No"
   sort="No" font="Verdana" bold="No" italic="No" appendkey="No"
   highlighthref="No" griddataalign="LEFT" gridlines="Yes"
   rowheaders="No" rowheaderalign="LEFT" rowheaderitalic="No"
   rowheaderbold="No" colheaders="Yes" colheaderalign="CENTER"
   colheaderitalic="No" colheaderbold="No" bgcolor="Teal"
   selectmode="BROWSE" picturebar="No">
   <cfgridcolumn name="LastName"
      header="Last Name" headeralign="LEFT" dataalign="LEFT"
      bold="No" italic="No" select="Yes" display="Yes" headerbold="No"
      headeritalic="No">
   <cfgridcolumn name="FirstName"
      header="First Name" headeralign="LEFT" dataalign="LEFT"
      fontsize="2" bold="No" italic="No" select="No" display="Yes"
      headerbold="No" headeritalic="No">
   <cfgridcolumn name="Email"
      header="Email" headeralign="LEFT" dataalign="LEFT" bold="No"
      italic="No" select="No" display="Yes" headerbold="No"
      headeritalic="No">
   <cfgridcolumn name="Phone"
      header="Phone" headeralign="LEFT" dataalign="LEFT" bold="No"
      italic="Yes" select="No" display="Yes" headerbold="No" headeritalic="No">
   <cfgridcolumn name="Department"
      header="Department" headeralign="LEFT" dataalign="LEFT" bold="Yes"
      italic="No" select="No" display="Yes" headerbold="No" headeritalic="No">
   <cfgridcolumn name="Emp_ID" header="ID" headeralign="LEFT" dataalign="LEFT"
      width="40" bold="No" italic="No" select="No" display="Yes" headerbold="No"
      headeritalic="No">
</cfgrid>
</cfform>


cfservlet

Description

This tag is deprecated. Do not use it in new applications. Executes a Java servlet on a JRun engine.

To access servlets that run on the same server as ColdFUsion, use code such as the following, in which path specifies a servlet, jsp, or anything else:

GetPageContext().include(path)
GetPageContext().forward(path)

For more information, see the JSP PageContext API or or the Servlet RequestDispatcher API.

History

New in ColdFusion MX: This tag is deprecated. Do not use it in new applications. It might not work, and it might cause an error, in later releases.


cfservletparam

Description

This tag is deprecated. Do not use it in new applications.

A child tag of the cfservlet tag. Passes data to a servlet. Each cfservletparam tag within the cfservlet block passes a separate item of data to the servlet.

To access servlets that run on the same server as ColdFUsion, use code such as the following, in which path specifies a servlet, jsp, or anything else:

GetPageContext().include(path)
GetPageContext().forward(path)

For more information, see the JSP PageContext API or or the Servlet RequestDispatcher API.

History

New in ColdFusion MX: This tag is deprecated. Do not use it in new applications. It might not work, and it might cause an error, in later releases.


cfset

Description

Defines a ColdFusion variable. If the variable exists, this tag sets it to the specified value.

Category

Variable manipulation tags

Syntax

<cfset
   variable_name = expression>

See also

cfcookie , cfparam , cfregistry , cfsavecontent , cfschedule

Attributes

Attribute | Req/Opt | Default | Description
variable_name | Required |  | Variable

Usage


Arrays

The following example assigns a new array to the variable months:

<cfset months = ArrayNew(1)>

This example creates a variable Array_Length that resolves to the length of the array Scores:

<cfset Array_Length = ArrayLen(Scores)>

This example assigns, to index position two in the array months, the value February:

<cfset months[2] = "February">


Dynamic variable names

In this example, the variable name is itself a variable:

<cfset myvariable = "current_value">
<cfset "#myvariable#" = 5>


COM objects

In this example, a COM object is created. A cfset defines a value for each method or property in the COM object interface. The last cfset creates a variable to store the return value from the COM object's SendMail method.

<cfobject action = "Create"
   name = "Mailer"
   class = "SMTPsvg.Mailer">

<cfset MAILER.FromName = form.fromname>
<cfset MAILER.RemoteHost = RemoteHost>
<cfset MAILER.FromAddress = form.fromemail>
<cfset MAILER.AddRecipient("form.fromname", "form.fromemail")>
<cfset MAILER.Subject = "Testing cfobject">
<cfset MAILER.BodyText = "form.msgbody">
<cfset Mailer.SMTPLog = "logfile">
<cfset success = MAILER.SendMail()>
<cfoutput> #success# </cfoutput>

Example

<!--- This example shows how to use cfset --->
<cfquery name = "GetMessages" dataSource = "cfsnippets">
   SELECT  *
   FROM   Messages
</cfquery>

<h3>cfset Example</h3>
<p>cfset sets and reassigns values to local or global variables within a page.

<cfset NumRecords = GetMessages.recordCount>
<p>For example, the variable NumRecords has been declared on this
page to hold the number of records returned from query
(<cfoutput>#NumRecords#</cfoutput>).

<p>In addition, cfset can be used to pass variables from other pages,
such as this example, which takes the url parameter Test from this link:
(<a href = "cfset.cfm?test = <cfoutput>
                  #URLEncodedFormat("hey, you, get off of my cloud")#               </cfoutput>
               ">click here</A>) to display a message:
<p>
<cfif IsDefined ("url.test") is "True">
   <cfoutput><b><I>#url.test#</i></b></cfoutput>
<cfelse>
   <h3>The variable url.test has not been passed from another page.</h3>
</cfif>

<p>cfset can also be used to collect environmental variables, such as the
time, the IP address of the user, or another function or expression.

<cfset the_date = #DateFormat(Now())# & " " & #TimeFormat(Now())#>
<cfset user_ip = CGI.REMOTE_ADDR>
<cfset complex_expr = (23 MOD 12) * 3>
<cfset str_example = Reverse(Left(GetMessages.body, 35))>

<cfoutput>
   <ul>
      <li>The date: #the_date#
      <li>User IP Address: #user_ip#
      <li>Complex Expression ((23 MOD 12) * 3): #complex_expr#
      <li>String Manipulation (the first 35 characters of
            the body of the first message in our query)
            <br><b>Reversed</b> :#str_example#
            <br><b>Normal</b>: #Reverse(str_example)#
   </ul>
</cfoutput>


cfsetting

Description

Controls aspects of page processing, such as the output of HTML code in pages.

Category

Page processing tags, Variable manipulation tags

Syntax

<cfsetting
   enableCFoutputOnly = "Yes" or "No"
   showDebugOutput = "Yes" or "No"
   requestTimeOut = "value in seconds" >

See also

cfcache , cfflush , cfheader , cfhtmlhead , cfinclude , cfsilent

History

New in ColdFusion MX: The requestTimeOut attribute is new.

New in ColdFusion MX: The catchExceptionsByPattern attribute is obsolete. Do not use it. It does not work, and causes an error, in releases later than ColdFusion 5.

New in ColdFusion 5.0: The structured exception manager searches for the best-fit cfcatch handler. (In earlier releases, an exception was handled by the first cfcatch block that could handle an exception of its type.)

Attributes

Attribute
Req/Opt
Default
Description
enableCFoutputOnly
Required
  • Yes: blocks output of HTML that is outside cfoutput tags
  • No
showDebugOutput
Optional
Yes
  • Yes
  • No: suppresses debugging information that would otherwise display at end of generated page.
requestTimeout
Optional
  • Integer; number of seconds. Time limit, after which ColdFusion processes the page as an unresponsive thread. Overrides the timeout set in the ColdFusion Administrator.

Usage

The cfsetting requestTimeout attribute replaces the use of requestTmeOut within a URL. To enforce a page timeout, detect the URL variable and use code such as the following to change the page timeout:

<cfsetting RequestTimeout = "#URL.RequestTimeout#">

You can use this tag to manage whitespace in ColdFusion output pages.

If you nest cfsetting tags: to make HTML output visible, you must match each enableCFoutputOnly = "Yes" statement with an enableCFoutputOnly = "No" statement. For example, after five enableCFoutputOnly = "Yes" statements, to enable HTML output, you must have five corresponding enableCFoutputOnly = "No" statements.

If HTML output is enabled (no matter how many enableCFoutputOnly = "No" statements have been processed) the first enableCFoutputOnly = "Yes" statement blocks output.

If the debugging service is enabled and showDebugOutput =" Yes", the IsDebugMode function returns Yes; otherwise, No.

Example

<p>CFSETTING is used to control the output of HTML code in Cold Fusion pages.
   This tag can be used to minimize the amount of generated whitespace.

<cfsetting enableCFoutputOnly = "Yes">
   This text is not shown
<cfsetting enableCFoutputOnly = "No">
   <p>This text is shown
<cfsetting enableCFoutputOnly = "Yes">
   <cfoutput>
      <p>Text within cfoutput is always shown
   </cfoutput>
<cfsetting enableCFoutputOnly = "No">
   <cfoutput>
      <p>Text within cfoutput is always shown
   </cfoutput>


cfsilent

Description

Suppresses output produced by CFML within a tag’s scope.

Category

Data output tags, Page processing tags

Syntax

<cfsilent>
...
</cfsilent>

See also

cfcache , cfflush , cfheader , cfhtmlhead , cfinclude , cfsetting

Usage

This tag requires an end tag.

Example

<h3>cfsilent</h3>

<cfsilent>
   <cfset a = 100>
   <cfset b = 99>
   <cfset c = b-a>
   <cfoutput>#c#</cfoutput>
</cfsilent>

<p>Even information within cfoutput tags does not display, within a
cfsilent block.<br>
b-c =
<cfoutput>
   #c#
</cfoutput>
</p>


cfslider

Description

Puts a slider control, for selecting a numeric value from a range, in a ColdFusion form. The slider moves over the slider groove. As the user moves the slider, the current value displays. Used within a cfform tag.

Category

Forms tags

Syntax

<cfslider
name = "name"
   label = "text"
   refreshLabel = "Yes" or "No"
   range = "min_value, max_value"
   scale = "uinteger"
   value = "integer"
   onValidate = "script_name"
   message = "text"
   onError = "text"
   height = "integer"
   width = "integer"
   vSpace = "integer"
   hSpace = "integer"
   align = "alignment"
   tickMarkMajor = "Yes" or "No"
   tickMarkMinor = "Yes" or "No"
   tickMarkImages = "URL1, URL2, URLn"
   tickMarkLabels = "Yes" or "No" or "list"
   lookAndFeel = "motif" or "windows" or "metal"
   vertical = "Yes" or "No"
   bgColor = "color"
   textColor = "color"
   font = "font_name"
   fontSize = "integer"
   italic = "Yes" or "No"
   bold = "Yes" or "No"
   notSupported = "text">

See also

cfapplet , cfinput , cfform , cfselect , cftextinput , cftree , cftreeitem

History

New in ColdFusion MX: The img, imgStyle, and grooveColor attributes are deprecated. Do not use them in new applications. They might not work, and might cause an error, in later releases.

Attributes

Attribute
Req/
Opt

Default

Description
name
Required
Name of cfslider control.
label
Optional
Label to display with control; for example, "Volume" This displays: "Volume %value%"
To reference the value, use "%value%". If %% is omitted, slider value displays directly after label.
refreshLabel
Optional
Yes
  • Yes: when user moves slider, label is refreshed
  • No
range
Optional
"0,100"
Numeric slider range values.
Separate values with a comma.
scale
Optional
Unsigned integer. Defines slider scale, within range. For example, if range = "0,1000" and scale = "100", the display values are:
0, 100, 200, 300, ...
Signed and unsigned integers in ColdFusion are in the range -2,147,483,648 to 2,147,483,647.
value
Optional
Minimum in range
Starting slider setting. Must be within the range values.
onValidate
Optional
Custom JavaScript function to validate user input; in this case, a change to the default slider value.
Specify only the function name.
message
Optional
Message text to appear if validation fails.
onError
Optional
Custom JavaScript function to execute if validation fails.
Specify only the function name.
height
Optional
40
Slider control height, in pixels.
width
Optional
Slider control width, in pixels.
vSpace
Optional
Vertical spacing above and below slider, in pixels.
hSpace
Optional
Horizontal spacing to left and right of slider, in pixels.
align
Optional
Alignment of slider
  • top
  • left
  • bottom
  • baseline
  • texttop
  • absbottom
  • middle
  • absmiddle
  • right
tickMarkMajor
Optional
No
  • Yes: render major tickmarks in slider scale.
  • No: no major tickmarks.
Major tick marks display at intervals specified by scale.
tickMarkMinor
Optional
No
  • Yes: render minor tickmarks in slider scale.
  • No: no minor tickmarks
Minor tickmarks display between major tickmarks.
tickMarkImages
Optional
Comma-delimited list of URLs specifying images in slider tickmark scale.
If you do not specify enough values, the last value is repeated for remaining tickmarks. If you specify too many values, extra values are ignored.
tickMarkLabels
Optional
No
  • yes: numeric tickmarks based on the value of the range and scale attributes.
  • no: prevents label text from displaying
  • Comma-delimited list of strings for tickmark labels; for example, "ten, twenty, thirty, forty"
If you do not specify enough values, the last value is repeated for remaining tickmarks. If you specify too many values, extra values are ignored.
lookAndFeel
Optional
Windows
  • motif: renders slider using Motif style
  • windows: renders slider using Windows style
  • metal: renders slider using Java Swing style
If platform does not support choice, the tag defaults to the platform’s default style.
vertical
Optional
No
  • Yes: renders slider in browser vertically. You must set width and height attributes; ColdFusion does not automatically swap width and height values.
  • No: renders slider horizontally.
bgColor
Optional
Background color of slider label.
For a hex value, use the form: bgColor = "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
  • Any color, in hex format
  • black
  • red
  • blue
  • magenta
  • cyan
  • orange
  • darkgray
  • pink
  • gray
  • white
  • lightgray
  • yellow
textColor
Optional
Options: same as for bgcolor attribute
font
Optional
Font name for label text.
fontSize
Optional
Font size for label text, in points.
italic
Optional
No
  • Yes: italics label text
  • No: normal text
bold
Optional
No
  • Yes: bold label text
  • No: medium text
notSupported
Optional
Text to display if a page that contains a Java applet-based cfform control is opened by a browser that does not support Java or has Java support disabled. For example:
"<b> Browser must support Java to view ColdFusion Java Applets</b>"
Default message:
<b>Browser must support Java to <br>view ColdFusion Java Applets!</b>

Usage

This tag requires the client to download a Java applet. Using this tag may be slightly slower than using an HTML form element to display the same information.

For this tag to work properly. the browser must be JavaScript-enabled.

If the following conditions are true, a user’s selection from query data that populates this tag’s options continues to display after the user submits the form:

  • The cfform preserveData attribute is set to "Yes"
  • The cfform action attribute posts to the same page as the form itself (this is the default), or the action page has a form that contains controls with the same names as corresponding controls on the user entry form

For more information, see the cfform tag entry.

Example

<!--- This example shows how to use cfslider within cfform --->
<h3>cfslider Example</h3>
<p>cfslider, used within a cfform, can provide functionality
   to Java-enabled browsers.
<p>Try moving the slider back and forth to see the real-time value change.
   Then, submit the form to show how cfslider passes its value on to a new page.
<cfif isdefined("form.mySlider") is true>
   <h3>You slid to a value of    <cfoutput>#mySlider#</cfoutput></h3>
   Try again!
</cfif>
<cfform action = "cfslider.cfm">
   <cfslider name = "mySlider" value = "12"
      label = "Actual Slider Value "
      range = "1,100" align = "BASELINE"
      message = "Slide the bar to get a value between 1 and 100"
      height = "50"       width = "150" font = "Verdana"
      bgColor = "Silver" bold = "No"
      italic = "Yes" refreshLabel = "Yes"> 100
<p><input type = "Submit" name = "" value = "Show the Result">
</cfform>


cfstoredproc

Description

Executes a stored procedure by a JDBC connection to a server database. It specifies database connection information and identifies the stored procedure.

Category

Database manipulation tags

Syntax

<cfstoredproc
   procedure = "procedure name"
   dataSource = "ds_name"
   username = "username"
   password = "password"
   blockFactor = "blocksize"
   debug = "Yes" or "No"
   returnCode = "Yes" or "No">

See also

cfinsert , cfqueryparam , cfprocparam , cfprocresult , cftransaction , cfquery , cfupdate

History

New in ColdFusion MX: The connectString, dbName, dbServer, dbtype, provider and providerDSN attributes are deprecated. Do not use them. They do not work, and might cause an error, in releases later than ColdFusion 5. (ColdFusion uses Type 4 JDBC drivers.)

Attributes

Attribute
Req/Opt
Default
Description
procedure
Required
Name of stored procedure on database server.
dataSource
Required
Name of data source that points to database that contains stored procedure.
username
Optional
Overrides username in data source setup.
password
Optional
Overrides password in data source setup.
blockFactor
Optional
1
Maximum number of rows to get at a time from server. Range is 1 to 100.
debug
Optional
No
  • Yes: Lists debug information on each statement
  • No
returnCode
Optional
No
  • Yes: Tag populates cfstoredproc.statusCode with status code returned by stored procedure.
  • No

Usage

Within this tag, you code cfprocresult and cfprocparam tags as necessary.

If you set returnCode = "Yes", this tag sets the variable cfstoredproc.statusCode, which holds the status code for a stored procedure. Status code values vary by DBMS. For the meaning of code values, see your DBMS documentation.

This tag sets the variable cfstoredproc.ExecutionTime, which contains the execution time of the stored procedure, in milliseconds.

Before implementing this tag, ensure that you understand stored procedures and their usage. The following examples use a Sybase stored procedure; for an example of an Oracle 8 stored procedure, see cfprocparam.

Example

<!--- This view-only example executes a Sybase stored procedure that
returns three result sets, two of which we want. The stored
procedure returns the status code and one output parameter,
which we display. We use named notation for the parameters. --->
<!---
<cfstoredproc procedure = "foo_proc"
   dataSource = "MY_SYBASE_TEST" username = "sa"
   password = "" dbServer = "scup" dbName = "pubs2"
   returnCode = "Yes" debug = "Yes">
   <cfprocresult name = RS1>
   <cfprocresult name = RS3 resultSet = 3>

   <cfprocparam type = "IN"       CFSQLType = CF_SQL_INTEGER
         value = "1" dbVarName = @param1>
   <cfprocparam type = "OUT" CFSQLType = CF_SQL_DATE
      variable = FOO dbVarName = @param2>
</cfstoredproc>
--->
<!---
<cfoutput>   The output param value: ’#foo#’<br></cfoutput>
<h3>The Results Information</h3>
<cfoutput query = RS1>#name#,#DATE_COL#<br></cfoutput><p>
<cfoutput>
   <hr>
   <p>Record Count: #RS1.recordCount# >p>Columns: #RS1.columnList#   <hr>
</cfoutput>
<cfoutput query = RS3>#col1#,#col2#,#col3#<br>
</cfoutput><p>
<cfoutput>
   <hr>
   <p>Record Count: #RS3.recordCount# <p>Columns: #RS3.columnList#   <hr>
   The return code for the stored procedure is: ’#cfstoredproc.statusCode#’<br>
</cfoutput>
--->


cfswitch

Description

Evaluates a passed expression and passes control to the cfcase tag that matches the expression result. You can, optionally, code a cfdefaultcase tag, which receives control if there is no matching cfcase tag value.

Category

Flow-control tags

Syntax

<cfswitch
   expression = "expression">
   <cfcase
      value = "value"
      delimiters = "delimiters">
      HTML and CFML tags
   </cfcase>
   additional <cfcase></cfcase> tags
   <cfdefaultcase>
     HTML and CFML tags
   </cfdefaultcase>
</cfswitch>

See also

cfabort , cfloop , cfbreak , cfrethrow , cfexecute , cfexit , cfthrow , cfif , cftry , cflocation

History

New in ColdFusion MX: you can put the cfdefaultcase tag at any position within a cfswitch statement; it is not required to be the last item.

Attributes

Attribute | Req/Opt | Default | Description
expression | Required |  | ColdFusion expression that yields a scalar value. ColdFusion converts integers, real numbers, Booleans, and dates to numeric values. For example, True, 1, and 1.0 are all equal.
value | Required |  | One or more constant values that cfswitch compares to the expression (case-insensitive). If a value matches expression, cfswitch executes the code between cfcase start and end tags. Duplicate value attributes cause a runtime error.
delimiters | Optional | , (comma) | Character that separates entries in a list of values.

Usage

This tag requires an end tag. All code within this tag must be within a cfcase or cfdefaultcase tag. Otherwise, ColdFusion throws an error.

Use this tag followed by one or more cfcase tags. Optionally, include a cfdefaultcase tag. This tag selects the matching alternative from the cfcase and cfdefaultcase tags, jumps to the matching tag, and executes the code between the cfcase start and end tags. You do not have to explicitly break out of the cfcase tag, as you do in some languages.

You can specify only one cfdefaultcase tag within a cfswitch tag. You can put the cfdefaultcase tag at any position within a cfswitch statement; it is not required to be the last item. For example:

<cfset foo=1>
<cfswitch expression="#foo#">
   <cfdefaultcase>
      <cfset fooMore= #foo# + 1>
   </cfdefaultcase>
   <cfcase value="2">
      <cfset fooMore = #foo# + 2>
   </cfcase>
</cfswitch>

<cfdump var=#fooMore#>

The cfswitch tag provides better performance than a series of cfif/cfelseif tags, and the code is easier to read.

Example

cfcase to
exercise a case statement in CFML --->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
   SELECT  Emp_ID, FirstName, LastName, EMail, Phone, Department
   FROM   Employees
</cfquery>

<h3>cfswitch Example</h3>
<!--- By outputting the query and using cfswitch, we classify the
output without using a cfloop construct. --->
<p>Each time the case is fulfilled, the specific information is printed;
if the case is not fulfilled, the default case is output </p>
<cfoutput query="GetEmployees">
<cfswitch expression="#Trim(Department)#">
   <cfcase value="Sales">
      #FirstName# #LastName# is in <b>sales</b><br><br>
   </cfcase>
   <cfcase value="Accounting">
      #FirstName# #LastName# is in <b>accounting</b><br><br>
   </cfcase> <cfcase value="Administration">
      #FirstName# #LastName# is in <b>administration</b><br><br>
   </cfcase>
   <cfdefaultcase>
      #FirstName# #LastName# is not in Sales, Accounting, or
         Administration.<br><br>
   </cfdefaultcase>
</cfswitch>
</cfoutput>


cftable

Description

Builds a table in a ColdFusion page. This tag renders data as preformatted text, or, with the HTMLTable attribute, in an HTML table. If you don't want to write HTML table tag code, or if your data can be presented as preformatted text, use this tag.

Preformatted text (defined in HTML with the <pre> and </pre> tags) displays text in a fixed-width font. It displays white space and line breaks exactly as they are written within the pre tags. For more information, see an HTML reference guide.

To define table column and row characteristics, use the cfcol tag within this tag.

Category

Data output tags

Syntax

<cftable
   query = "query_name"
   maxRows = "maxrows_table"
   colSpacing = "number_of_spaces"
   headerLines = "number_of_lines"
   HTMLTable
   border
   colHeaders
   startRow = "row_number">
   ...
</cftable>

See also

cfcol , cfoutput , cfcontent , cfprocessingdirective , cflog , cftable

Attributes

Attribute | Req/Opt | Default | Description
query | Required |  | Name of cfquery from which to draw data.
maxRows | Optional |  | Maximum number of rows to display in the table.
colSpacing | Optional | 2 | Number of spaces between columns
headerLines | Optional | 2 | Number of lines to use for table header (the default leaves one line between header and first row of table).
HTMLTable | Optional |  | Renders data in an HTML 3.0 table. If you use this attribute (regardless of its value), ColdFusion renders data in an HTML table.
border | Optional |  | Displays border around table. If you use this attribute (regardless of its value), ColdFusion displays a border around the table. Use this only if you use the HTMLTable attribute.
colHeaders | Optional |  | Displays column heads. If you use this attribute, you must also use the cfcol tag header attribute to define them. If you use this attribute (regardless of its value), ColdFusion displays column heads.
startRow | Optional | 1 | The query result row to put in the first table row.

Usage

This tag aligns table data, sets column widths, and defines column heads.

At least one cfcol tag is required within this tag. You must put cfcol and cftable tags adjacent in a page. The only tag that you can nest within this tag is the cfcol tag. You cannot nest cftable tags.

To display the cfcol header text, you must specify the cfcol header and the cftable colHeader attribute. If you specify either attribute without the other, the header does not display and no error is thrown.

Example

<!--- This example shows the use of cfcol and cftable to align information
returned from a query --->
<!--- This query selects employee information from cfsnippets datasource --->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
   SELECT Emp_ID, FirstName, LastName, EMail, Phone, Department
   FROM Employees
</cfquery>

<html>
<body>
<h3>cftable Example</h3>

<!--- Note use of HTMLTable attribute to display cftable as an HTML table,
rather than as PRE formatted information --->
<cftable query = "GetEmployees"
   startRow = "1" colSpacing = "3" HTMLTable>
<!--- each cfcol tag sets width of a column in table, and specifies header
information and text/CFML with which to fill cell --->
   <cfcol header = "<b>ID</b>"
      align = "Left"
      width = 2
      text  = "#Emp_ID#">

   <cfcol header = "<b>Name/Email</b>"
      align = "Left"
      width = 15
      text  = "<a href = ’mailto:#Email#’>#FirstName# #LastName#</A>">

   <cfcol header = "<b>Phone Number</b>"
      align = "Center"
      width = 15
      text  = "#Phone#">
</cftable>
</body>
</html>


cftextinput

Description

Puts a single-line text entry box in a cfform tag and controls its display characteristics.

Category

Forms tags

Syntax

<cftextinput
   name = "name"
   value = "text"
   required = "Yes" or "No"
   range = "min_value, max_value"
   validate = "data_type"
   onValidate = "script_name"
   message = "text"
   onError = "text"
   size = "integer"
   font = "font_name"
   fontSize = "integer"
   italic = "Yes" or "No"
   bold = "Yes" or "No"
   height = "integer"
   width = "integer"
   vSpace = "integer"
   hSpace = "integer"
   align = "alignment"
   bgColor = "color"
   textColor = "color"
   maxLength = "integer"
   notSupported = "text">

See also

cfapplet , cfform , cfgrid , cfgridcolumn , cfgridrow , cfgridupdate , cfinput , cfselect , cfslider , cftree , cftreeitem

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name for the cftextinput control.
value
Optional
Initial value to display in text control.
required
Optional
No
  • Yes: the user must enter or change text
  • No
range
Optional
Minimum–maximum value range, delimited by a comma. Valid only for numeric data.
validate
Optional
  • date: verifies format mm/dd/yy.
  • eurodate: verifies date format dd/mm/yyyy.
  • time: verifies time format hh:mm:ss.
  • float: verifies floating point format.
  • integer: verifies integer format.
  • telephone: verifies telephone format ###-###-####. The separator can be a blank. Area code and exchange must begin with digit 1 - 9.
  • zipcode: verifies, in U.S. formats only, 5- or 9-digit format #####-####. The separator can be a blank.
  • creditcard: strips blanks and dashes; verifies number using mod10 algorithm.
  • social_security_number: verifies format ###-##-####. The separator can be a blank.
  • regular_expression: matches input against pattern attribute.
onValidate
Optional
Custom JavaScript function to validate user input. The form object, input object, and input object value are passed to routine, which should return True if validation succeeds, False otherwise. The validate attribute is ignored.
pattern
Required if validate = "regular_
expression"
JavaScript regular expression pattern to validate input. Omit leading and trailing slashes.
message
Optional
Message text to display if validation fails.
onError
Optional
Custom JavaScript function to execute if validation fails.
size
Optional
Number of characters displayed before horizontal scroll bar displays.
font
Optional
Font name for text.
fontSize
Optional
Font size for text.
italic
Optional
No
  • Yes: italics text
  • No: normal text
bold
Optional
No
  • Yes: bold text
  • No: medium text
height
Optional
40
Height of the control, in pixels.
width
Optional
200
Width of the control, in pixels.
vSpace
Optional
Vertical spacing of the control, in pixels.
hSpace
Optional
Horizontal spacing of the control, in pixels.
align
Optional
Alignment of text entry box with respect to adjacent HTML content:
  • top
  • left
  • bottom
  • baseline
  • texttop
  • absbottom
  • middle
  • absmiddle
  • right
bgColor
Optional
Background color of control. For a hex value, use the form: textColor = "##xxxxxx", where x = 0-9 or A-F; use two pound signs or none.
  • any color, in hex format
  • black
  • red
  • blue
  • magenta
  • cyan
  • orange
  • darkgray
  • pink
  • gray
  • white
  • lightgray
  • yellow
textColor
Optional
Text color for control.
Options: same as for bgcolor attribute.
maxLength
Optional
The maximum length of text entered.
notSupported
Optional
Text to display if a page that contains a Java applet-based cfform control is opened by a browser that does not support Java, or has Java support disabled. For example:
notSupported = "<b> Browser must support Java to view ColdFusion Java Applets</b>"
If no message is specified, this message displays:
<b>Browser must support Java to <br> view ColdFusion Java Applets!</b>

Usage

This tag requires the client to download a Java applet. Downloading an applet takes time; therefore, using this tag might be slightly slower than using an HTML form element or the cfinput tag to get the same information.

For this tag to work properly. the browser must be JavaScript-enabled.

If the following conditions are true, a user’s selection from query data that populates this tag’s options continues to display after the user submits the form:

  • The cfform preserveData attribute is set to "Yes"
  • The cfform action attribute posts to the same page as the form itself (this is the default), or the action page has a form that contains controls with the same names as corresponding controls on the user entry form

For more information, see cfform.

If the cfform preserveData attribute is "yes", and the form posts back to the same page, the posted value (not the value of the value attribute) of the cftextinput control is used.

Example

<h3>cftextinput Example</h3>
cftextinput provides simple validation for text fields in cfform and
control over font information displayed in cfform input boxes
for text. For example, the field below must not be blank, and
provides a client-side message upon erring.
<cfform action = "cftextinput.cfm" method = "post">
<cfif IsDefined("form.myInput")>
   <h3>You entered
      <cfoutput>
         #form.myInput#</cfoutput> into the text box </h3>
</cfif>

<cftextinput name = "myInput"
   font = "Courier" fontSize = 12
   value = "Look, this text is red!"
   textColor = "FF0000"
   message = "This field must not be blank"
   required = "Yes">

<input type = "Submit" name = "" value = "submit">
</cfform>


cfthrow

Description

Throws a developer-specified exception, which can be caught with a cfcatch tag that has any of the following type attribute options:

  • type = "custom_type"
  • type = "Application"
  • type = "Any"

Category

Exception handling tags, Flow-control tags

Syntax 1

<cfthrow
   type = "exception_type "
   message = "message"
   detail = "detail_description "
   errorCode = "error_code "
   extendedInfo = "additional_information"
   object = "java_except_object">

Syntax 2

<cfthrow
   object = #object_name#>

See also

cferror , cfrethrow , cftry

History

New in ColdFusion MX: this tag can throw ColdFusion component method exceptions.

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
Application
  • A custom type
  • Application
Do not enter another predefined type; types are not generated by ColdFusion applications. If you specify Application, you need not specify a type for cfcatch.
message
Optional
Message that describes exception event.
detail
Optional
Description of the event. ColdFusion appends error position to description; server uses this parameter if an error is not caught by your code.
errorCode
Optional
A custom error code that you supply.
extendedInfo
Optional
A custom error code that you supply.
object
Optional
Requires the value of the cfobject tag name attribute.
Throws a Java exception from a CFML tag.
This attribute is mutually exclusive with all other attributes of this tag.

Usage

Use this tag within a cftry block, to throw an error. The cfcatch block can access accompanying information, as follows:

  • Message, with cfcatch.message
  • Detail, with cfcatch.detail
  • Error code, with cfcatch.errorcode

To get more information, use cfcatch.tagContext. This shows where control switches from one page to another in the tag stack (for example, cfinclude, cfmodule).

To display the information displayed by tagContext: in the ColdFusion Administrator, Debugging page, select Enable CFML Stack Trace.

To use this tag with the object parameter, you must define an exception using the cfobject tag, with code such as the following:

<cfobject
type="java"
action="create"
class="coldfusion.tagext.InvalidTagAttributeException"
name="obj">
<cfset obj.init("Attribute", "value")>

With this code, the cfthrow statement would be as follows:

<cfthrow object=#obj#>

The cfthrow tag passes exception parameters to the obj variable.

Example

<h3>cfthrow Example</h3>
<!--- open a cftry block --->
<cftry>
<!--- define a condition upon which to throw the error --->
<cfif NOT IsDefined("URL.myID")>
   <!--- throw the error --->
   <cfthrow message = "ID is not defined">
</cfif>

<!--- perform the error catch --->
<cfcatch type = "application">
<!--- display your message --->
   <h3>You've Thrown an <b>Error</b></h3>
<cfoutput>
   <!--- and the diagnostic feedback from the application server --->
  <p>#cfcatch.message#</p>
   <p>The contents of the tag stack are:</p>
   <cfloop
      index = i
      from = 1 to = #ArrayLen(cfcatch.tagContext)#>
          <cfset sCurrent = #cfcatch.tagContext[i]#>
             <br>#i# #sCurrent["ID"]#
            (#sCurrent["LINE"]#,#sCurrent["COLUMN"]#)
            #sCurrent["TEMPLATE"]#
   </cfloop>
</cfoutput>
</cfcatch>
</cftry>


cftrace

Description

Displays and logs debugging data about the state of an application at the time the cftrace tag executes. Tracks runtime logic flow, variable values, and execution time. Displays output at the end of the request or in the debugging section at the end of the request; or, in Dreamweaver MX and later, in in the Server Debug tab of the Results window.

ColdFusion logs cftrace output to the file logs\cftrace.log, in the ColdFusion installation directory.

Note: To permit this tag to execute, you must enable debugging in the ColdFusion Administrator. Optionally, to report trace summaries, enable the Trace section.

Category

Debugging tags, Variable manipulation tags

Syntax

<cftrace
   abort = "Yes or No"
   category = "string"
   inline = "Yes or No"
   text = "string"
   type = "format"
   var = "variable_name"
</cftrace>

See also

cfdump , cferror , cfrethrow , cftry

History

New in ColdFusion MX: this tag is new.

Attributes

Attribute
Req/Opt
Default
Description
abort
Optional
No
  • Yes: calls cfabort tag when the tag is executed
  • No
category
Optional
User-defined string for identifying trace groups
inline
Optional
No
  • Yes: displays trace code in addition to the trace summary display.
  • No
text
Optional
User-defined string or simple variable. Outputs to cflog text attribute.
type
Optional
Information
Matches to the cflog type attribute; displays an appriate icon.
  • Information
  • Warning
  • Error
  • Fatal Information
var
Optional
The name of a simple or complex variable to display.
Useful for displaying a temporary value, or a value that does not display on any CFM page.

Usage

You cannot put application code within this tag. (This avoids problems that can occur if you disable debugging.)

This tag is useful for debugging CFML code during application development.

You can display cftrace tag output in the following ways:

  • As a section in the debugging output
  • In-line in an application page, and as a section in debugging output. If you specify in-line tracing, ColdFusion flushes all output up to the cftrace tag, and displays the trace output when it encounters the tag.

This is an example of a log file entry:

"Information","web-4","04/08/02","23:21:30",   ,"[30 ms (1st trace)]
[C:\cfusion\wwwroot\generic.cfm @ line: 9] -
   [thisPage = /generic.cfm]  "
"Information","web-0","04/08/02","23:58:58",   ,"[5187 ms (10)]
[C:\cfusion\wwwroot\generic.cfm @ line: 14] - [category]
   [thisPage = /generic.cfm] [ABORTED] thisPage "

For a complex variable, ColdFusion lists the variable name and the number of elements in the object; it does not log the contents of the variable.

The following example traces a FORM variable that is evaluated by a cfif block:

Example

<cftrace var="FORM.variable"
   text="doing equivalency check for FORM.variable"
   category="form_vars"
   inline="true">
<cfif isDefined("FORM.variable") AND #FORM.variable# EQ 1>
   <h1>Congratulations, you're a winner!</h1>
<cfelse>
   <h1>Sorry, you lost!</h1>
</cfif>


cftransaction

Description

Groups database queries into a unit. Provides database commit and rollback processing.

Category

Database manipulation tags

Syntax

<cftransaction
   action = "begin" or "commit" or "rollback"
   isolation = "read_uncommitted" or "read_committed" or
      "repeatable_read" >
</cftransaction>

See also

cfinsert , cfprocparam , cfprocresult , cfquery , cfqueryparam , cfstoredproc , cfupdate

Attributes

Attribute
Req/Opt
Default
Description
action
Optional
begin
  • begin: the start of the block of code to execute.
  • commit: commits a pending transaction
  • rollback: rolls back a pending transaction
isolation
Optional
ODBC lock type.
  • read_uncommitted
  • read_committed
  • repeatable_read
  • serializable

Usage

Within a transaction block, you can do the following:

  • Commit a database transaction by nesting the <cftransaction action = "commit"/> tag within the block
  • Roll back a transaction by nesting the <cftransaction action = "rollback"/> tag within the block

(In these examples, the slash is alternate syntax that is the equivalent of an end tag.)

Within a transaction block, you can write queries to more than one database, but you must commit or rollback a transaction to one database before writing a query to another. Using CFML error handling, you control whether each transaction is committed, based on the success or failure of the database query. To control how the database engine performs locking during the transaction, use the isolation attribute.

Example

<p>CFTRANSACTION can be used to group multiple queries that use CFQUERY
into one business event.  Changes to data that is requested by the queries
are not committed to the datasource until all actions within the transaction
block have executed successfully.
<p>This a view-only example.
<!---
<cftransaction>
   <cfquery name='makeNewCourse' datasource='Snippets'>
   INSERT INTO Courses
      (Number, Descript)
   VALUES
      ('#myNumber#', '#myDescription#')
   </cfquery>

   <cfquery name='insertNewCourseToList' datasource='Snippets'>
   INSERT INTO CourseList
      (CorNumber, CorDesc, Dept_ID,
      CorName, CorLevel, LastUpdate)
   VALUES
      ('#myNumber#', '#myDescription#', '#myDepartment#',
      '#myDescription#', '#myCorLevel#', #Now()#)
   </cfquery>
</cftransaction>
--->


cftree

Description

Inserts a tree control in a form. Validates user selections. Used within a cftree tag block. You can use a ColdFusion query to supply data to the tree.

Category

Forms tags

Syntax

<cftree name = "name"
   required = "Yes" or "No"
   delimiter = "delimiter"
   completePath = "Yes" or "No"
   appendKey = "Yes" or "No"
   highlightHref = "Yes" or "No"
   onValidate = "script_name"
   message = "text"
   onError = "text"
   lookAndFeel = "motif" or "windows" or "metal"
   font = "font"
   fontSize = "size"
   italic = "Yes" or "No"
   bold = "Yes" or "No"
   height = "integer"
   width = "integer"
   vSpace = "integer"
   hSpace = "integer"
   align = "alignment"
   border = "Yes" or "No"
   hScroll = "Yes" or "No"
   vScroll = "Yes" or "No"
   notSupported = "text">

</cftree>

See also

cfapplet , cfform , cfgrid , cfgridcolumn , cfgridrow , cfgridupdate , cfinput , cfselect , cfslider , cftextinput , cftree , cftreeitem

History

New in ColdFusion MX: ColdFusion renders a tree control regardless of whether there are any treeitems within it.

Attributes

Attribute
Req/Opt
Default
Description
name
Required
Name for tree control.
required
Optional
No
  • Yes: user must select an item in tree control
  • No
delimiter
Optional
\\
Character to separate elements in form variable path.
completePath
Optional
No; tree name is returned as root
  • Yes: passes the root part of treename.path form variable when cftree is submitted
  • No, or omitted: root level of form variable is not passed; path value starts with the first node
For the preserveData attribute of cfform to work with the tree, you must set this attribute to Yes.
If you specify a root name for a tree item with cftreeitem queryasroot, that value is returned. If you do not specify a root name, ColdFusion returns the query name as the root.
appendKey
Optional
Yes
  • Yes: when used with href, passes CFTREEITEMKEY variable with the value of the selected tree item in URL to the application page specified in the cfform action attribute
  • No
highlightHref
Optional
Yes
  • Yes: highlights links that are associated with a cftreeitem with a URL attribute value
  • No: disables highlight
onValidate
Optional
JavaScript function to validate user input. The form object, input object, and input object value are passed to the specified routine, which should return True if validation succeeds; False, otherwise.
message
Optional
Message to display if validation fails.
onError
Optional
JavaScript function to execute if validation fails.
lookAndFeel
Optional
windows
  • motif: renders slider in Motif style
  • windows: renders slider in Windows style
  • metal: renders slider in Java Swing style
If platform does not support style option, tag defaults to platform default style.
font
Optional
Font name for data in tree control.
fontSize
Optional
Font size for text in tree control, in points.
italic
Optional
No
  • Yes: displays tree control text in italics
  • No
bold
Optional
No
  • Yes: displays tree control text in bold
  • No
height
Optional
320
Tree control height, in pixels.
width
Optional
200
Tree control width, in pixels.
vSpace
Optional
Vertical margin above and below tree control, in pixels.
hSpace
Optional
Horizontal spacing to left and right of tree control, in pixels.
align
Optional
  • top
  • left
  • bottom
  • baseline
  • texttop
  • absbottom
  • middle
  • absmiddle
  • right
border
Optional
Yes
  • Yes
  • No
hScroll
Optional
Yes
  • Yes: permits horizontal scrolling
  • No
vScroll
Optional
Yes
  • Yes: permits vertical scrolling
  • No
notSupported
Optional
Message to display if page that contains Java applet-based form control is opened by browser that does not support Java, or has Java support disabled. For example:
notSupported = "<b> Browser must support Java to view ColdFusion Java Applets</b>"
If no message is specified, this message displays:
<b>Browser must support Java to <br> view ColdFusion Java Applets!</b>

Usage

This tag requires the client to download a Java applet. Downloading an applet takes time; therefore, using this tag might be slightly slower than using an HTML form element or the cfinput tag to get the same information.

For this tag to work properly. the browser must be JavaScript-enabled.

If the following conditions are true, a user’s selection from query data that populates this tag’s options continues to display after the user submits the form:

  • The cfform preserveData attribute is set to "Yes"
  • The cfform action attribute posts to the same page as the form itself (this is the default), or the action page has a form that contains controls with the same names as corresponding controls on the user entry form

For more information, see the cfform tag entry.

Example

<!--- This example shows the use of cftree in a cfform. The query takes a list of
employees, and uses cftree and cfselect to display the results. cfgrid is
used to show an alternate means of displaying the same data --->
<!--- set a default for the employeeNames variable --->
<cfparam name = "employeeNames" default = "">
<!--- if an employee name has been passed from the form, set employeeNames
variable to this value --->
<cfif IsDefined("form.employeeNames")>
   <cfset employeeNames = form.employeeNames>
</cfif>
<!--- query the datasource to find the employee information--->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
   SELECT  Emp_ID, FirstName, LastName, EMail, Phone, Department
   FROM   Employees where lastname
     <cfif #employeeNames# is not ""> = ’#employeeNames#’</cfif>
</cfquery>
<html>
<body>
<h3>cftree Example</h3>
<!--- Use cfform when using other cfinput tools --->
<cfform action = "cftree.cfm">
<!--- Use cfselect to present the contents of the query by column --->
<h3>cfselect Presentation of Data</h3>
<h4>Click an employee’s last name and "see information for this employee",
to see expanded information.</h4>
<cfselect name = "EmployeeNames" message = "Select an Employee Name"
   size = "#getEmployees.recordcount#" query = "GetEmployees"
  value = "LastName" required = "No">
   <option value = "">Select All
</cfselect>
<input type = "Submit" name = ""
   value = "see information for this employee">
<!--- showing the use of cftree --->
<!--- Use cftree for an expanded presentation of the data --->
<!--- Loop through the query to create each branch of the cftree --->
<h3>cftree Presentation of Data</h3>
<h4>Click on the folders to "drill down" and reveal information.</h4>
<p>cftreeitem is used to create the "branches" of the tree.
<p>
<cftree name = "SeeEmployees" height = "150" width = "240"
   font = "Arial Narrow" bold = "No"
   italic = "No" border = "Yes"
   hScroll = "Yes" vScroll = "Yes"
   required = "No" completePath = "No"
   appendKey = "Yes" highlightHref = "Yes">
<cfloop query = "GetEmployees">
   <cftreeitem value = "#Emp_ID#" parent = "SeeEmployees" expand = "No">
   <cftreeitem value = "#LastName#" display = "Name"
      parent = "#Emp_ID#" queryAsRoot = "No"
      expand = "No">
   <cftreeitem value = "#LastName#, #FirstName#"
      parent = "#LastName#" expand = "No"
      queryAsRoot = "No">
   <cftreeitem value = "#Department#" display = "Department"
      parent = "#Emp_ID#" queryAsRoot = "No"
      expand = "No">
   <cftreeitem value = "#Department#" parent = "#Department#"
      expand = "No" queryAsRoot = "No">
   <cftreeitem value = "#Phone#" display = "Phone"
      parent = "#Emp_ID#" queryAsRoot = "No"
      expand = "No">
   <cftreeitem value = "#Phone#" parent = "#Phone#"
      expand = "No" queryAsRoot = "No">
   <cftreeitem value = "#Email#" display = "Email" parent = "#Emp_ID#"
       queryAsRoot = "No" expand = "No">
   <cftreeitem value = "#Email#" parent = "#Email#" expand = "No"
      queryAsRoot = "No">
</cfloop>
</cftree>
...


cftreeitem

Description

Populates a form tree control, created with the cftree tag, with elements. To display icons, you can use the img values that ColdFusion provides, or reference your own icons.

Category

Forms tags

Syntax

<cftreeitem
   value = "text"
   display = "text"
   parent = "parent_name"
   img = "filename"
   imgopen = "filename"
   href = "URL"
   target = "URL_target"
   query = "queryname"
   queryAsRoot = "Yes" or "No"
   expand = "Yes" or "No">

See also

cfapplet , cfform , cfgrid , cfgridcolumn , cfgridrow , cfgridupdate , cfinput , cfselect , cfslider , cftextinput , cftree

Attributes

Attribute
Req/Opt
Default
Description
value
Required
Value passed when cfform is submitted. When populating a tree with data from a cfquery, specify columns in a delimited list. Example: value = "dept_id,emp_id"
display
Optional
value
Tree item label. When populating a tree with data from a query, specify names in a delimited list. Example: display = "dept_name,emp_name"
parent
Optional
Value for tree item parent.
img
Optional
folder
Image name, filename, or file URL for tree item icon.
The following values are provided:
  • cd
  • computer
  • document
  • element
  • folder
  • floppy
  • fixed
  • remote
You can specify a custom image. To do so, include path and file extension; for example:
img = "../images/page1.gif"
To specify more than one image in a tree, or an image at the second or subsequent level, use commas to separate names, corresponding to level; for example:
img = "folder,document"
img = ",document" (example of second level)
imgopen
Optional
Icon displayed with open tree item. You can specify icon filename with a relative path. You can use a ColdFusion image.
href
Optional
URL to associate with tree item or query column for a tree that is populated from a query. If href is a query column, its value is the value populated by query. If href is not recognized as a query column, it is assumed that its text is an HTML href.
When populating a tree with data from a query, HREFs can be specified in delimited list; for example:
href = "http://dept_svr,http://emp_svr"
target
Optional
Target attribute of href URL. When populating a tree with data from a query, specify target in delimited list:
target = "FRAME_BODY,_blank"
query
Optional
Query name to generate data for the treeitem.
queryAsRoot
Optional
Defines query as the root level. This avoids having to create another parent cftreeitem.
  • Yes
  • No
  • String to use as the root name
If you do not specify a root name, ColdFusion returns the query name as the root.
expand
Optional
Yes
  • Yes: expands tree to show tree item children
  • No: keeps tree item collapsed

Usage

This tag requires the client to download a Java applet. Downloading an applet takes time; therefore, using this tag might be slightly slower than using an HTML form element or the cfinput tag to get the same information.

For this tag to work properly. the browser must be JavaScript-enabled.

Example

<!--- This example shows the use of cftreeitem in cfform. Query takes
employee list, and uses cftree and cfselect to display query results.
Shows an alternate means of displaying the data --->
<!--- set a default for the employeeNames variable --->
<cfparam name = "employeeNames" default = "">
<!--- if an employee name has been passed from the form, set employeeNames
variable to this value ---Auto>
<cfif IsDefined("form.employeeNames")>
   <cfset employeeNames = form.employeeNames>
</cfif>
<!--- query the datasource to find the employee information--->
<cfquery name = "GetEmployees" dataSource = "cfsnippets">
SELECT  Emp_ID, FirstName, LastName, EMail, Phone, Department
FROM   Employees
   WHERE 0=0
   <cfif employeeNames is not "">
         AND LastName = '#employeeNames#'
   </cfif>
</cfquery>

<!--- Use cfform when using other cfinput tools --->
<cfform action = "cfindex.cfm">
<!--- Use cfselect to present the contents of the query by column --->
<h3>cfselect Presentation of Data</h3>
<h4>Click an employee’s last name and click "see information for this employee"
   to see expanded information.</h4>

<cfselect name = "EmployeeNames" message = "Select an Employee Name"
   size = "#getEmployees.recordcount#" query = "GetEmployees"
  value = "LastName" required = "No">
   <option value = "">Select All
</cfselect>

<input type = "Submit" name = ""
   value = "see information for this employee">
<!--- showing use of cftree for expanded presentation of data --->
<!--- Loop through the query to create each branch of the cftree --->
<h3>cftree Presentation of Data</h3>
<h4>Click the folders to "drill down" and reveal information.</h4>
<p>cftreeitem is used to create the branches of the cftree.

<p><cftree name = "SeeEmployees" height = "150" width = "240"
   font = "Arial Narrow" bold = "No"    italic = "No" border = "Yes"
   hScroll = "Yes" vScroll = "Yes"    required = "No" completePath = "No"
   appendKey = "Yes" highlightHref = "Yes">
<cfloop query = "GetEmployees">
   <cftreeitem value = "#Emp_ID#" parent = "SeeEmployees" expand = "No">
   <cftreeitem value = "#LastName#" display = "Name"
      parent = "#Emp_ID#" queryAsRoot = "No"       expand = "No">
   <cftreeitem value = "#LastName#, #FirstName#"
      parent = "#LastName#" expand = "No"       queryAsRoot = "No">
   <cftreeitem value = "#Department#" display = "Department"
      parent = "#Emp_ID#" queryAsRoot = "No"       expand = "No">
   <cftreeitem value = "#Department#"
      parent = "#Department#"       expand = "No" queryAsRoot = "No">
   <cftreeitem value = "#Phone#" display = "Phone"
      parent = "#Emp_ID#" queryAsRoot = "No"       expand = "No">
   <cftreeitem value = "#Phone#"
      parent = "#Phone#"       expand = "No" queryAsRoot = "No">
   <cftreeitem value = "#Email#" display = "Email"
      parent = "#Emp_ID#" queryAsRoot = "No"       expand = "No">
   <cftreeitem value = "#Email#"
      parent = "#Email#"       expand = "No" queryAsRoot = "No">
</cfloop>
</cftree>

<!--------For a more comprehensive, quicker view, you can use CFGRID ------->
<h3>cfgrid Presentation of Data</h3>
<cfgrid name="SampleGrid" width="600" query="GetEmployees"    insert="No"
   delete="No" sort="No" font="Verdana" bold="No"    italic="No" appendkey="No"
   highlighthref="No" griddataalign="LEFT"    gridlines="Yes" rowheaders="No"
   rowheaderalign="LEFT" rowheaderitalic="No"       rowheaderbold="No" colheaders="Yes"
   colheaderalign="CENTER"    colheaderitalic="No" colheaderbold="No"
   bgcolor="Teal" selectmode="BROWSE" picturebar="No">
<cfgridcolumn name="LastName" header="Last Name" headeralign="LEFT"
   dataalign="LEFT" bold="No" italic="No" select="Yes" display="Yes"
   headerbold="No" headeritalic="No"> <cfgridcolumn name="FirstName"
   header="First Name" headeralign="LEFT" dataalign="LEFT" fontsize="2"
   bold="No" italic="No" select="No" display="Yes" headerbold="No"
   headeritalic="No">
<cfgridcolumn name="Email" header="Email" headeralign="LEFT" dataalign="LEFT"
   bold="No" italic="No" select="No" display="Yes" headerbold="No"
   headeritalic="No">
<cfgridcolumn name="Phone" header="Phone" headeralign="LEFT" dataalign="LEFT"
   bold="No" italic="Yes" select="No" display="Yes" headerbold="No"
   headeritalic="No"> <cfgridcolumn name="Department" header="Department"
   headeralign="LEFT" dataalign="LEFT" bold="Yes" italic="No" select="No"
   display="Yes" headerbold="No" headeritalic="No">
<cfgridcolumn name="Emp_ID" header="ID" headeralign="LEFT" dataalign="LEFT"
   width="40" bold="No" italic="No" select="No" display="Yes" headerbold="No"
   headeritalic="No">
</cfgrid>
</cfform>


cftry

Description

Used with one or more cfcatch tags. Together, they catch and process exceptions in ColdFusion pages. Exceptions are events that disrupt the normal flow of instructions in a ColdFusion page, such as failed database operations, missing include files, and developer-specified events.

Category

Exception handling tags

Syntax

<cftry>
   code here
<cfcatch type = "exceptiontype">
   Exception processing code here
</cfcatch>
   Optional: More cfcatch blocks here
</cftry>

See also

cfcatch , cferror , cfrethrow , cfthrow

History

New in ColdFusion MX: The SQLSTATE return value in a cfcatch tag depends on the database driver type:

  • Type 1 (JDBC-ODBC bridge): the value is the same as in ColdFusion 5
  • Type 4 (100% Java, no native methods): the value might be different

If your application depends on SQLSTATE values for flow control, the application might produce unexpected behavior with ColdFusion MX.

New in ColdFusion MX: it is not necessary, when you include a cfcatch tag with type="any", to do so in the last cfcatch tag in the block, to ensure that all other tests are executed before it. ColdFusion finds the best-match cfcatch block.

New in ColdFusion MX: the cftry and cfcatch tags can be used as cfscript constructs, and for handling component method invocation errors.

New in ColdFusion MX: you cannot modify the structure returned by cfcatch.

New in ColdFusion MX: The cfcollection, cfindex, and cfsearch tags can throw the SEARCHENGINE exception. In earlier releases, an error in processing these tags threw only an UNKNOWN exception.

Attributes

Attribute
Req/Opt
Default
Description
type
Optional
Any
  • application: catches application exceptions
  • database: catches database exceptions
  • template: catches ColdFusion page exceptions
  • security: catches security exceptions
  • object: catches object exceptions
  • missinginclude: catches missing include file exceptions
  • expression: catches expression exceptions
  • lock: catches lock exceptions
  • custom_type: catches developer-defined exceptions, defined in the cfthrow tag
  • searchengine: catches Verity search engine exceptions
  • any: catches all exception types

Usage

Within a cftry block, you must code at least one cfcatch tag. Put cfcatch tags at the end of a cftry block. ColdFusion tests cfcatch tags in the order in which they appear.

If type="any", ColdFusion Server catches exceptions from any CFML tag, data source, or external object. To get the exception type use code such as the following:

   #cfcatch.type#

Applications can use the cfthrow tag to throw developer-defined exceptions. Catch these exceptions with any of these type options:

  • "custom_type"
  • "Application"
  • "Any"

The custom_type type is a developer-defined type specified in a cfthrow tag. If you define a custom type as a series of strings concatenated by periods (for example, "MyApp.BusinessRuleException.InvalidAccount"), the cfcatch tag can catch the custom type by its character pattern. The tag searches for a matching exception type, starting with the most specific (the entire string), and ending with the least specific.

For example, you could define a type as follows:

   <cfthrow type = "MyApp.BusinessRuleException.InvalidAccount">

The cfcatch tag first searches the cfthrow tag for the entire type string:

   <cfcatch type = "MyApp.BusinessRuleException.InvalidAccount">

If it does not find a match, it searches for the next most specific:

<cfcatch type = "MyApp.BusinessRuleException">

Finally, it searches for the least specific:

   <cfcatch type = "MyApp">

You can code cfcatch tags in any order to catch a custom exception type.

If you specify type = "Application", the cfcatch tag catches only custom exceptions that have the Application type in the cfthrow tag that defines them.

The cfinclude, cfmodule, and cferror tags throw an exception of type = "template".

An exception that is thrown within a cfcatch block cannot be handled by the cftry block that immediately encloses the cfcatch tag. However, you can rethrow the currently active exception with the cfrethrow tag.

The following example shows how to throw an exception from a component method:

<cfcomponent>
   <cffunction name="getEmp">
   <cfargument name="lastName" required="yes">
       <cfquery name="empQuery" datasource="ExampleApps" >
          SELECT LASTNAME, FIRSTNAME, EMAIL
          FROM tblEmployees
         WHERE LASTNAME LIKE '#arguments.lastName#'
       </cfquery>
       <cfif empQuery.recordcount LT 1>
          <cfthrow type="noQueryResult"
            message="No results were found. Please try again.">
         <cfelse>
              <cfreturn empQuery>
        </cfif>
   </cffunction>
</cfcomponent>

For an explanation of the example and more information, see the "Building and Using ColdFusion Components" chapter in Developing ColdFusion Applications.

The cfcatch variables provide the following exception information:

cfcatch variable | Content
cfcatch.type | Type: Exception type, as specified in cfcatch.
cfcatch.message | Message: Exception's diagnostic message, if provided; otherwise, an empty string; in the cfcatch.message variable
cfcatch.detail | Detailed message from CFML interpreter. The message contains HTML formatting. It can help determine which tag threw the exception.
cfcatch.tagcontext | Tag stack name, position of each tag in the stack, and absolute pathnames of the files that contain the tags in the stack.
cfcatch.NativeErrorCode | Applies to type = "database". Native error code associated with exception. Database drivers typically provide error codes to diagnose failing database operations. Default: -1.
cfcatch.SQLState | Applies to type ="database". SQLState associated with exception. Database drivers typically provide error codes to help diagnose failing database operations. Default: -1.
cfcatch.ErrNumber | Applies to type="expression". Internal expression error number.
cfcatch.MissingFileName | Applies to type="missingInclude". Name of file that could not be included.
cfcatch.LockName | Applies to type="lock". Name of affected lock (if the lock is unnamed, the value is "anonymous").
cfcatch.LockOperation | Applies to type="lock". Operation that failed (Timeout, Create Mutex, or Unknown).
cfcatch.ErrorCode | Applies to type="custom". String error code.
cfcatch.ExtendedInfo | Applies to type="application" and "custom". Custom error message; information that the default exception handler does not display.


Advanced Exception types

You can specify the following advanced exception types in the type attribute:

ColdFusion Advanced Exception type
COM.Allaire.ColdFusion.CFEXECUTE.OutputError
COM.Allaire.ColdFusion.CFEXECUTE.Timeout
COM.Allaire.ColdFusion.FileException
COM.Allaire.ColdFusion.HTTPAccepted
COM.Allaire.ColdFusion.HTTPAuthFailure
COM.Allaire.ColdFusion.HTTPBadGateway
COM.Allaire.ColdFusion.HTTPBadRequest
COM.Allaire.ColdFusion.HTTPCFHTTPRequestEntityTooLarge
COM.Allaire.ColdFusion.HTTPCGIValueNotPassed
COM.Allaire.ColdFusion.HTTPConflict
COM.Allaire.ColdFusion.HTTPContentLengthRequired
COM.Allaire.ColdFusion.HTTPContinue
COM.Allaire.ColdFusion.HTTPCookieValueNotPassed
COM.Allaire.ColdFusion.HTTPCreated
COM.Allaire.ColdFusion.HTTPFailure
COM.Allaire.ColdFusion.HTTPFileInvalidPath
COM.Allaire.ColdFusion.HTTPFileNotFound
COM.Allaire.ColdFusion.HTTPFileNotPassed
COM.Allaire.ColdFusion.HTTPFileNotRenderable
COM.Allaire.ColdFusion.HTTPForbidden
COM.Allaire.ColdFusion.HTTPGatewayTimeout
COM.Allaire.ColdFusion.HTTPGone
COM.Allaire.ColdFusion.HTTPMethodNotAllowed
COM.Allaire.ColdFusion.HTTPMovedPermanently
COM.Allaire.ColdFusion.HTTPMovedTemporarily
COM.Allaire.ColdFusion.HTTPMultipleChoices
COM.Allaire.ColdFusion.HTTPNoContent
COM.Allaire.ColdFusion.HTTPNonAuthoritativeInfo
COM.Allaire.ColdFusion.HTTPNotAcceptable
COM.Allaire.ColdFusion.HTTPNotFound
COM.Allaire.ColdFusion.HTTPNotImplemented
COM.Allaire.ColdFusion.HTTPNotModified
COM.Allaire.ColdFusion.HTTPPartialContent
COM.Allaire.ColdFusion.HTTPPaymentRequired
COM.Allaire.ColdFusion.HTTPPreconditionFailed
COM.Allaire.ColdFusion.HTTPProxyAuthenticationRequired
COM.Allaire.ColdFusion.HTTPRequestURITooLarge
COM.Allaire.ColdFusion.HTTPResetContent
COM.Allaire.ColdFusion.HTTPSeeOther
COM.Allaire.ColdFusion.HTTPServerError
COM.Allaire.ColdFusion.HTTPServiceUnavailable
COM.Allaire.ColdFusion.HTTPSwitchingProtocols
COM.Allaire.ColdFusion.HTTPUnsupportedMediaType
COM.Allaire.ColdFusion.HTTPUrlValueNotPassed
COM.Allaire.ColdFusion.HTTPUseProxy
COM.Allaire.ColdFusion.HTTPVersionNotSupported
COM.Allaire.ColdFusion.POPAuthFailure
COM.Allaire.ColdFusion.POPConnectionFailure
COM.Allaire.ColdFusion.POPDeleteError
COM.Allaire.ColdFusion.Request.Timeout
COM.Allaire.ColdFusion.SERVLETJRunError
COMCOM.Allaire.ColdFusion.HTTPConnectionTimeout

This tag requires an end tag.

Example

<!--- cftry example, using TagContext to display the tag stack. --->
<h3>cftry Example</h3>
<!--- open a cftry block --->
<cftry>
   <!--- note misspelled tablename "employees" as "employeeas" --->
   <cfquery name = "TestQuery" dataSource = "cfsnippets">
      SELECT *
      FROM EMPLOYEEAS
   </cfquery>

   <!--- <p>... other processing goes here --->
   <!--- specify the type of error for which we search --->
   <cfcatch type = "Database">
   <!--- the message to display --->
      <h3>You've Thrown a Database <b>Error</b></h3>
      <cfoutput>
         <!--- and the diagnostic message from the ColdFusion server --->
         <p>#cfcatch.message#</p>
         <p>Caught an exception, type = #CFCATCH.TYPE# </p>
         <p>The contents of the tag stack are:</p>
         <cfloop index = i from = 1
               to = #ArrayLen(CFCATCH.TAGCONTEXT)#>
            <cfset sCurrent = #CFCATCH.TAGCONTEXT[i]#>
            <br>#i# #sCurrent["ID"]#
               (#sCurrent["LINE"]#,#sCurrent["COLUMN"]#)
               #sCurrent["TEMPLATE"]#
         </cfloop>
      </cfoutput>
   </cfcatch>
</cftry>


cfupdate

Description

Updates records in a data source from data in a ColdFusion form or form Scope.

Category

Database manipulation tags

Syntax

<cfupdate
   dataSource = "ds_name"
   tableName = "table_name"
   tableOwner = "name"
   tableQualifier = "qualifier"
   username = "username"
   password = "password"
   formFields = "field_names">

See also

cfinsert , cfprocparam , cfprocresult , cfquery , cfqueryparam , cfstoredproc , cftransaction

History

New in ColdFusion MX: The connectString, dbName, dbServer, dbtype, provider and providerDSN attributes are deprecated. Do not use them. They do not work, and might cause an error, in releases later than ColdFusion 5.

Attributes

Attribute
Req/Opt
Default
Description
dataSource
Required
Name of the data source that contains the table.
tableName
Required
Name of table to update.
  • For ORACLE drivers, must be uppercase.
  • For Sybase driver: case-sensitive; must be in same case as used when the table was created
tableOwner
Optional
For data sources that support table ownership (for example, SQL Server, Oracle, Sybase SQL Anywhere), the table owner.
tableQualifier
Optional
For data sources that support table qualifiers. The purpose of table qualifiers is as follows:
  • SQL Server and Oracle: name of database that contains table
  • Intersolv dBASE driver: directory of DBF files
username
Optional
Overrides username value specified in ODBC setup.
password
Optional
Overrides password value specified in ODBC setup.
formFields
Optional
(all on form, except keys)
Comma-delimited list of form fields to update.
If a form field is not matched by a column name in the database, ColdFusion throws an error.
The database table key field must be present in the form. It can be hidden.

Example

<!--- This example shows the use of CFUPDATE to change
records in a datasource. --->
<!--- if course_ID has been passed to this form, then
perform the update on that record in the datasource --->

<cfif IsDefined("form.Course_ID")>
   <!--- check that course_id is numeric --->
      <cfif Not IsNumeric(form.Course_ID)>
         <cfabort>
      </cfif>
   <!--- Now, do the update --->
   <cfupdate datasource="cfsnippets"
      tablename="Courses"
      formfields="Course_ID,Number,Descript">
</cfif>

<!--- Perform a query to reflect any updated information if Course_ID is passed
through a url, we are selecting a record to update ... select only that
record with the WHERE clause. --->
<cfquery name="GetCourseInfo" DATASOURCE="cfsnippets">
   SELECT Course_Number, Course_ID, Descript
   FROM Courses
      <cfif IsDefined("url.Course_ID")>
         WHERE Course_ID = #Trim(url.Course_ID)#
      </cfif>
   ORDER by Course_Number
</cfquery>
<html>
<head>
   <title>CFUPDATE Example</title>
   <cfset css_path = "../../css">
   <cfinclude template="../../resource/include/mm_browsersniff.cfm">
</head>
<body>

<H3>CFUPDATE Example</H3>
<!--- If we are updating a record, don't show the entire list. --->
<cfif IsDefined("url.Course_ID")>
   <form method="post" action="index.cfm">
   <H3>You can alter the contents of this record, and then click "Update"
      to use CFUPDATE and alter the database</H3>
   <P>Course Number <INPUT TYPE="Text" name="Number"
value="<cfoutput>#Trim(GetCourseInfo.Course_Number)#</cfoutput>">
   <P>Course Description<BR>
   <textarea name="Descript" cols="40" rows="5">
      <cfoutput>#Trim(GetCourseInfo.Descript)#</cfoutput>
   </textarea><br>
   <input type="Hidden" NAME="Course_ID"
      value="<cfoutput>#Trim(GetCourseInfo.Course_ID)#</cfoutput>">
   <p><input type="Submit" value="Click to Update">
   </form>

<cfelse>
   <!--- Show the entire record set in CFTABLE form --->
   <cftable query="GetCourseInfo" htmltable colheaders>
      <cfcol text="<a href='index.cfm?Course_ID=#Trim(Course_ID)#'>Edit Me</a>"
         width=10 header="Edit<br>this Entry">
      <cfcol text="#Trim(Course_Number)#" WIDTH="4" HEADER="Course Number">
      <cfcol text="#Trim(Descript)#" WIDTH=100 HEADER="Course Description">
   </cftable>
</cfif>
</body>
</html>


cfwddx

Description

Serializes and deserializes CFML data structures to the XML-based WDDX format. The WDDX is an XML vocabulary for describing complex data structures in a standard, generic way. Implementing it lets you use the HTTP protocol to such information among application server platforms, application servers, and browsers.

This tag generates JavaScript statements to instantiate JavaScript objects equivalent to the contents of a WDDX packet or CFML data structure. Interoperates with Unicode.

Category

Extensibility tags

Syntax

<cfwddx
   action = "action"
   input = "inputdata"
   output = "resultvariablename"
   topLevelVariable = "toplevelvariablenameforjavascript"
   useTimeZoneInfo = "Yes" or "No"
   validate = "Yes" or "No" >

See also

cfcollection , cfdump , cfexecute , cfindex , cfobject , cfreport , cfsearch

History

New in ColdFusion MX: ColdFusion preserves the case of column names in JavaScript. (Earlier releases converted query column names to lowercase.)

New in ColdFusion MX: This tag supports several encoding formats. The default encoding format is UTF-8. The tag interoperates with Unicode.

Attributes

Attribute
Req/Opt
Default
Description
action
Required
  • cfml2wddx: serialize CFML to WDDX
  • wddx2cfml: deserialize WDDX to CFML
  • cfml2js: serialize CFML to JavaScript
  • wddx2js: deserialize WDDX to JavaScript
input
Required
A value to process
output
Required if action = "wddx2cfml"
Name of variable for output. If action = "WDDX2JS" or "CFML2JS", and this attribute is omitted, result is output in HTML stream.
topLevelVariable
Required if action = "wddx2js" or "cfml2js"
Name of top-level JavaScript object created by deserialization. The object is an instance of the WddxRecordset object.
useTimeZoneInfo
Optional
Yes
Whether to output time-zone information when serializing CFML to WDDX.
  • Yes: the hour-minute offset, represented in ISO8601 format, is output.
  • No: the local time is output.
validate
Optional
No
Applies if action = "wddx2cfml" or "wddx2js".
  • yes: validates WDDX input with an XML parser using WDDX DTD. If parser processes input without error, packet is deserialized. Otherwise, an error is thrown.
  • no: no input validation

Usage

ColdFusion preserves the case of column names cases in JavaScript.

The wddx2js and cfml2js actions create a WddxRecordset javascript object when they encounter a RecordSet java object. The serialized JavaScript code requires a wddx.js file.

This tag performs the following conversions:

From | To
CFML | WDDX
CFML | JavaScript
WDDX | CFML
WDDX | JavaScript

For more information, and a list of the ColdFusion array and structure functions that you can use to manage XML document objects and functions, see Developing ColdFusion MX Applications with CFML.

Example

<!--- This shows basic use of the cfwddx tag. --->
<html>
<body>
<!--- Create a simple query --->
<cfquery name = "q" dataSource = "cfsnippets">
   select Message_Id, Thread_id, Username from messages
</cfquery>

The recordset data is:...<p>
<cfoutput query = q>
   #Message_ID# #Thread_ID# #Username#<br>
</cfoutput><p>

<!--- Serialize data to WDDX format --->
Serializing CFML data...<p>
<cfwddx action = "cfml2wddx" input = #q# output = "wddxText">

<!--- Display WDDX XML packet --->
Resulting WDDX packet is:
<xmp><cfoutput>#wddxText#</cfoutput></xmp>

<!--- Deserialize to a variable named wddxResult --->
Deserializing WDDX packet...<p>
<cfwddx action = "wddx2cfml" input = #wddxText# output = "qnew">

The recordset data is:...<p>
<cfoutput query = qnew>
   #Message_ID# #Thread_ID# #Username#<br>
</cfoutput><p>


cfxml

Description

Creates a ColdFusion XML document object that contains the markup in the tag body. This tag can include XML and CFML tags. ColdFusion processes the CFML code in the tag body, then assigns the resulting text to an XML document object variable.

Category

Extensibility tags

Syntax

<CFXML
   variable="xmlVarName"
   caseSensitive="yes" or "no">

See also

IsXmlDoc , IsXmlElement , IsXmlRoot , XmlChildPos , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: This tag is new.

Attributes

Attribute
Req/Opt
Default
Description
variable
name of an xml variable
caseSensitive
Optional
no
  • yes: maintains the case of document elements and attributes
  • no

Usage

An XML document object is represented in ColdFusion as a structure.

The following example creates a document object whose root element is MyDoc. The object includes text that displays the value of the ColdFusion variable testVar. The code creates four nested child elements, which are generated by an indexed cfloop tag. The cfdump tag displays the XML document object.

Example

<cfset testVar = True>
<cfxml variable="MyDoc">
   <MyDoc>
      <cfif testVar IS True>
         <cfoutput>The value of testVar is True.</cfoutput>
      <cfelse>
         <cfoutput>The value of testVar is False.</cfoutput>
      </cfif>
      <cfloop index = "LoopCount" from = "1" to = "4">
         <childNode>
            This is Child node <cfoutput>#LoopCount#.</cfoutput>
         </childNode>
      </cfloop>
   </MyDoc>
</cfxml>
<cfdump var=#MyDoc#>

Previous


ColdFusion Function Summary

This chapter lists and categorizes ColdFusion Markup Language (CFML) functions.

Contents
  • New functions, parameters, and values
  • Obsolete functions, parameters, and values
  • Function summary
  • Array functions
  • Authentication functions
  • Conversion functions
  • Date and time functions
  • Decision functions
  • Display and formatting functions
  • Dynamic evaluation functions
  • Extensibility functions
  • Full-text search functions
  • International functions
  • List functions
  • Mathematical functions
  • Other functions
  • Query functions
  • String functions
  • Structure functions
  • System functions
  • XML functions
Next


New functions, parameters, and values

Function | Parameter or value | New in this ColdFusion Server release
CreateObject | All | ColdFusion MX
GetPageContext | All | ColdFusion MX
GetMetaData | All | ColdFusion MX
GetProfileSections | All | ColdFusion MX
IsK2ServerABroker | All | ColdFusion MX
IsK2ServerOnline | All | ColdFusion MX
IsObject | All | ColdFusion MX
IsProtected | All | ColdFusion MX
IsUserInRole | All | ColdFusion MX
IsXmlDoc | All | ColdFusion MX
IsXmlElement | All | ColdFusion MX
IsXmlRoot | All | ColdFusion MX
SetEncoding | All | ColdFusion MX
SetLocale | variant attribute | ColdFusion MX
URLDecode | charset attribute | ColdFusion MX
URLEncodedFormat | charset attribute | ColdFusion MX
XmlChildPos | All | ColdFusion MX
XmlElemNew | All | ColdFusion MX
XmlFormat | All | ColdFusion MX
XmlNew | All | ColdFusion MX
XmlParse | All | ColdFusion MX
XmlSearch | All | ColdFusion MX
XmlTransform | All | ColdFusion MX


Deprecated functions, parameters, and values

The following functions, parameters, and values are deprecated. Do not use them in ColdFusion applications. They might not work, and might cause an error, in releases later than ColdFusion MX.

Function

Parameter or value
Deprecated as of this ColdFusion
Server release
getMetricData
cachepops parameter
ColdFusion MX
getK2ServerCollections
All
ColdFusion MX
getTemplatePath
All
ColdFusion MX
parameterExists
All
ColdFusion MX. Use the IsDefined function.
setLocale
locale = "Spanish (Mexican)" value
ColdFusion MX. Use Spanish (Standard).
URLEncodedFormat
All
ColdFusion MX


Obsolete functions, parameters, and values

The following functions, parameters, and values are obsolete. Do not use them. Do not use them in ColdFusion applications. They might not work, and might cause an error, in release later than ColdFusion 5.

Function

Parameter or value
Deprecated as of this ColdFusion
Server release
AuthenticatedContext
All
ColdFusion MX
AuthenticatedUser
All
ColdFusion MX
isAuthenticated
All
ColdFusion MX
isAuthorized
All
ColdFusion MX
isProtected
All
ColdFusion MX


Function summary

ColdFusion Markup Language (CFML) includes a set of functions that you use in ColdFusion pages to perform logical and arithmetic operations and manipulate data.

The following table lists CFML functions:

Abs | GetHttpTimeString | Max
ACos | GetK2ServerDocCount | Mid
ArrayAppend | GetK2ServerDocCountLimit | Min
ArrayAvg | GetLocale | Minute
ArrayClear | GetMetaData | Month
ArrayDeleteAt | GetMetricData | MonthAsString
ArrayInsertAt | GetPageContext | Now
ArrayIsEmpty | GetProfileSections | NumberFormat
ArrayLen | GetProfileString | ParagraphFormat
ArrayMax | GetServiceSettings | ParameterExists
ArrayMin | GetTempDirectory | ParseDateTime
ArrayNew | GetTempFile | Pi
ArrayPrepend | GetTemplatePath | PreserveSingleQuotes
ArrayResize | GetTickCount | Quarter
ArraySet | GetTimeZoneInfo | QueryAddColumn
ArraySort | GetToken | QueryAddRow
ArraySum | Hash | QueryNew
ArraySwap | Hour | QuerySetCell
ArrayToList | HTMLCodeFormat | QuotedValueList
Asc | HTMLEditFormat | Rand
ASin | IIf | Randomize
Atn | IncrementValue | RandRange
BitAnd | InputBaseN | REFind
BitMaskClear | Insert | REFindNoCase
BitMaskRead | Int | RemoveChars
BitMaskSet | IsArray | RepeatString
BitNot | IsBinary | Replace
BitOr | IsBoolean | ReplaceList
BitSHLN | IsCustomFunction | ReplaceNoCase
BitSHRN | IsDate | REReplace
BitXor | IsDebugMode | REReplaceNoCase
Ceiling | IsDefined | Reverse
Chr | IsK2ServerABroker | Right
CJustify | IsK2ServerDocCountExceeded | RJustify
Compare | IsK2ServerOnline | Round
CompareNoCase | IsLeapYear | RTrim
Cos | IsNumeric | Second
CreateDate | IsNumericDate | SetEncoding
CreateDateTime | IsObject | SetLocale
CreateObject | IsQuery | SetProfileString
CreateODBCDate | IsSimpleValue | SetVariable
CreateODBCDateTime | IsStruct | Sgn
CreateODBCTime | IsUserInRole | Sin
CreateTime | IsWDDX | SpanExcluding
CreateTimeSpan | IsXmlDoc | SpanIncluding
CreateUUID | IsXmlElement | Sqr
DateAdd | IsXmlRoot | StripCR
DateCompare | JavaCast | StructAppend
DateConvert | JSStringFormat | StructClear
DateDiff | LCase | StructCopy
DateFormat | Left | StructCount
DatePart | Len | StructDelete
Day | ListAppend | StructFind
DayOfWeek | ListChangeDelims | StructFindKey
DayOfWeekAsString | ListContains | StructFindValue
DayOfYear | ListContainsNoCase | StructGet
DaysInMonth | ListDeleteAt | StructInsert
DaysInYear | ListFind | StructIsEmpty
DE | ListFindNoCase | StructKeyArray
DecimalFormat | ListFirst | StructKeyExists
DecrementValue | ListGetAt | StructKeyList
Decrypt | ListInsertAt | StructNew
DeleteClientVariable | ListLast | StructSort
DirectoryExists | ListLen | StructUpdate
DollarFormat | ListPrepend | Tan
Duplicate | ListQualify | TimeFormat
Encrypt | ListRest | ToBase64
Evaluate | ListSetAt | ToBinary
Exp | ListSort | ToString
ExpandPath | ListToArray | Trim
FileExists | ListValueCount | UCase
Find | ListValueCountNoCase | URLDecode
FindNoCase | LJustify | URLEncodedFormat
FindOneOf | Log | URLSessionFormat
FirstDayOfMonth | Log10 | Val
Fix | LSCurrencyFormat | ValueList
FormatBaseN | LSDateFormat | Week
GetAuthUser | LSEuroCurrencyFormat | WriteOutput
GetBaseTagData | LSIsCurrency | XmlChildPos
GetBaseTagList | LSIsDate | XmlElemNew
GetBaseTemplatePath | LSIsNumeric | XmlFormat
GetClientVariablesList | LSNumberFormat | XmlNew
GetCurrentTemplatePath | LSParseCurrency | XmlParse
GetDirectoryFromPath | LSParseDateTime | XmlSearch
GetException | LSParseEuroCurrency | XmlTransform
GetFileFromPath | LSParseNumber | Year
GetFunctionList | LSTimeFormat | YesNoFormat
GetHttpRequestData | LTrim |


Array functions

ArrayAppend | ArrayIsEmpty | ArrayPrepend | ArraySwap
ArrayAvg | ArrayLen | ArrayResize | ArrayToList
ArrayClear | ArrayMax | ArraySet | IsArray
ArrayDeleteAt | ArrayMin | ArraySort | ListToArray
ArrayInsertAt | ArrayNew | ArraySum |


Authentication functions

GetAuthUser
IsUserInRole


Conversion functions

ArrayToList | Hash | URLEncodedFormat | XmlTransform
ToBase64 | LCase | Val |
ToBinary | ListToArray | XmlFormat |
ToString | URLDecode | XmlParse |


Date and time functions

CreateDate | DateFormat | GetTimeZoneInfo | MonthAsString
CreateDateTime | DatePart | Hour | Now
CreateODBCDate | Day | IsDate | ParseDateTime
CreateODBCDateTime | DayOfWeek | IsLeapYear | Quarter
CreateODBCTime | DayOfWeekAsString | IsNumericDate | Second
CreateTime | DayOfYear | LSDateFormat | TimeFormat
CreateTimeSpan | DaysInMonth | LSIsDate | Week
DateAdd | DaysInYear | LSParseDateTime | Year
DateCompare | FirstDayOfMonth | LSTimeFormat |
DateConvert | GetHttpTimeString | Minute |
DateDiff | GetTickCount | Month |


Decision functions

DirectoryExists | IsDate | IsNumericDate | IsXmlElement
FileExists | IsDebugMode | IsObject | IsXmlRoot
IIf | IsDefined | IsQuery | LSIsCurrency
IsArray | IsK2ServerABroker | IsSimpleValue | LSIsDate
IsAuthenticated | IsK2ServerDocCountExceeded | IsStruct | LSIsNumeric
IsBinary | IsK2ServerOnline | IsUserInRole | StructIsEmpty
IsBoolean | IsLeapYear | IsWDDX | StructKeyExists
IsCustomFunction | IsNumeric | IsXmlDoc | YesNoFormat


Display and formatting functions

CJustify | HTMLEditFormat | LSNumberFormat | ParagraphFormat
DateFormat | LJustify | LSParseCurrency | RJustify
DecimalFormat | LSCurrencyFormat | LSParseDateTime | SetEncoding
DollarFormat | LSDateFormat | LSParseEuroCurrency | StripCR
FormatBaseN | LSEuroCurrencyFormat | LSParseNumber | TimeFormat
GetLocale | LSIsCurrency | LSTimeFormat | YesNoFormat
HTMLCodeFormat | LSIsDate | NumberFormat |


Dynamic evaluation functions

DE
Evaluate
IIf
SetVariable


Extensibility functions

CreateObject | XmlElemNew | XmlNew | XmlSearch
XmlChildPos | XmlFormat | XmlParse | XmlTransform


Full-text search functions

GetK2ServerDocCount | IsK2ServerABroker | IsK2ServerDocCountExceeded | IsK2ServerOnline
GetK2ServerDocCountLimit |  |  |


International functions

DateConvert | LSCurrencyFormat | LSIsNumeric | LSParseNumber
GetHttpTimeString | LSDateFormat | LSNumberFormat | LSTimeFormat
GetLocale | LSEuroCurrencyFormat | LSParseCurrency |
GetTimeZoneInfo | LSIsDate | SetLocale |
LSIsCurrency | LSParseDateTime | LSParseEuroCurrency |


List functions

ArraySort | FindOneOf | ListDeleteAt | ListSetAt
ArrayToList | FormatBaseN | ListFind | ListSort
Asc | ListContainsNoCase | ListFindNoCase | ListToArray
Chr | GetClientVariablesList | ListFirst | ListValueCount
CJustify | LCase | ListGetAt | ListValueCountNoCase
Compare | Left | ListInsertAt | ReplaceList
CompareNoCase | Len | ListLast |
Decrypt | ListAppend | ListLen |
Encrypt | ListChangeDelims | ListPrepend |
Find | ListContains | ListQualify |
FindNoCase | ListContainsNoCase | ListRest |


Mathematical functions

Abs | BitNot | FormatBaseN | Randomize
ACos | BitOr | IncrementValue | RandRange
ArrayAvg | BitSHLN | InputBaseN | Round
ArraySum | BitSHRN | Int | Sgn
ASin | BitXor | Log | Sin
Atn | Ceiling | Log10 | Sqr
BitAnd | Cos | Max | Tan
BitMaskClear | DecrementValue | Min |
BitMaskRead | Exp | Pi |
BitMaskSet | Fix | Rand |


Other functions

CreateUUID | GetBaseTagList | QuotedValueList | URLEncodedFormat
Decrypt | GetBaseTemplatePath | StripCR | URLSessionFormat
DeleteClientVariable | GetClientVariablesList | ToBase64 | ValueList
Duplicate | GetTickCount | ToBinary | WriteOutput
Encrypt | Hash | ToString |
GetBaseTagData | PreserveSingleQuotes | URLDecode |


Query functions

IsQuery | QueryAddRow | QuerySetCell | ValueList
QueryAddColumn | QueryNew | QuotedValueList |


String functions

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode character values 0–65535. (Earlier releases supported ASCII values.)

String-processing functions process any of these characters (including ASCII 0 (NUL) characters), and continue counting subsequent characters of the string, if any. (In earlier releases, some string-processing functions processed the ASCII 0 (NUL) character, but did not process subsequent characters of the string.)

Asc | JavaCast | LTrim | Right
Chr | JSStringFormat | Mid | RJustify
CJustify | LCase | MonthAsString | RTrim
Compare | Left | ParagraphFormat | SpanExcluding
CompareNoCase | Len | ParseDateTime | SpanIncluding
DayOfWeekAsString | LJustify | REFind | StripCR
Decrypt | ListValueCount | REFindNoCase | ToBase64
Encrypt | ListValueCountNoCase | RemoveChars | ToBinary
FormatBaseN | LSIsCurrency | RepeatString | ToString
Find | LSIsDate | Replace | Trim
FindNoCase | LSIsNumeric | ReplaceList | UCase
FindOneOf | LSParseCurrency | ReplaceNoCase | URLDecode
GetToken | LSParseDateTime | REReplace | URLEncodedFormat
Hash | LSParseEuroCurrency | REReplaceNoCase | Val
Insert | LSParseNumber | Reverse | XmlFormat

See also Conversion functions.


Structure functions

Duplicate | StructCount | StructGet | StructKeyList
IsStruct | StructDelete | StructInsert | StructNew
StructAppend | StructFind | StructIsEmpty | StructSort
StructClear | StructFindKey | StructKeyArray | StructUpdate
StructCopy | StructFindValue | StructKeyExists |


System functions

DirectoryExists | GetException | GetMetricData | SetProfileString
ExpandPath | GetFileFromPath | GetProfileString | GetPageContext
FileExists | GetFunctionList | GetTempDirectory | GetProfileSections
GetBaseTemplatePath | GetHttpRequestData | GetTempFile | GetServiceSettings
GetCurrentTemplatePath | GetLocale | SetEncoding | SetLocale
GetDirectoryFromPath | GetMetaData | GetTemplatePath |


XML functions

IsXmlDoc | XmlElemNew | XmlNew | XmlSearch
XmlChildPos | XmlFormat | XmlParse | XmlTransform
Previous


ColdFusion Functions: Abs--JSStringFormat

This chapter describes ColdFusion Markup Language (CFML) functions.

Next


Abs

Description

Absolute-value function. The absolute value of a number is the number without its sign.

Return value

The absolute value of a number.

Category

Mathematical functions

Syntax

Abs(number)

See also

Sgn

Parameters

Parameter | Description
number | A number

Example

<h3>Abs Example</h3>
<p>The absolute value of the following numbers:
1,3,-4,-3.2,6 is
<cfoutput>
#Abs(1)#,#Abs(3)#,#Abs(-4)#,#Abs(-3.2)#,#Abs(6)#
</cfoutput>

<p>The absolute value of a number is the number without its sign.


ACos

Description

Arccosine function. The arccosine is the angle whose cosine is number.

Return value

The arccosine of a number, in radians.

Category

Mathematical functions

Syntax

ACos(number)

See also

Cos , Sin , ASin , Tan , Pi

Parameters

Parameter | Description
number | Cosine of an angle. The value must be between -1.0 and 1.0, inclusive.

Usage

The range of the result is 0 to p.

To convert degrees to radians, multiply degrees by p/180. To convert radians to degrees, multiply radians by 180/p.

Example

<h3>ACos Example</h3>
<!--- output its arccosine value --->
<cfif IsDefined("FORM.CosNum")>
   <cfif IsNumeric(FORM.CosNum)>
      <cfif FORM.CosNum LESS THAN OR EQUAL TO 1>
         <cfif FORM.CosNum GREATER THAN OR EQUAL TO -1>
            ACos(<cfoutput>#FORM.CosNum#</cfoutput>) = <cfoutput>#ACos(FORM.cosNum)#
Radians            </cfoutput>
            <br> or            <br>
            ACos(<cfoutput>#FORM.CosNum#</cfoutput>) =
            <cfoutput>#Evaluate(ACos(FORM.cosNum) * 180/PI())# Degrees</cfoutput>
         <cfelse>
            <!--- if it is empty, output an error message --->
            <h4>Enter a number between -1 and 1</h4>
            </cfif>
      <cfelse>
         <!--- if it is empty, output an error message --->
         <h4>Enter a number between -1 and 1</h4>
      </cfif>
   </cfif>
</cfif>

<form action = "acos.cfm">
<p>Enter a number to get its arccosine in Radians and Degrees.
<br><input type = "Text" name = "cosNum" size = "25">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


ArrayAppend

Description

Appends an array element to an array.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayAppend(array, value)

See also

ArrayPrepend

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
array | Name of an array
value | Value to add at end of array

Example

<h3>ArrayAppend Example</h3>
<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
SELECT FirstName, LastName FROM Employees
</cfquery>
<!--- create an array --->
<cfset myArray = ArrayNew(1)>
<!--- set element one to show where we are --->
<cfset myArray[1] = "Test Value">
<!--- loop through the query; append these names successively to the last
element --->
<cfloop query = "GetEmployeeNames">
   <cfoutput>#ArrayAppend(myArray, "#FirstName# #LastName#")#
   </cfoutput>, Array was appended<br>
</cfloop>
<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>
<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the array are as follows:
   <p>#myList#
</cfoutput>


ArrayAvg

Description

Calculates the average of the values in an array.

Return value

Number. If the array parameter value is an empty array, returns zero.

Category

Array functions , Mathematical functions

Syntax

ArrayAvg(array)

See also

ArraySum

Parameters

Parameter | Description
array | Name of an array

Usage

The following example uses the ColdFusion built-in variable Form.fieldNames, which is available on the action page of a form. It contains a comma-delimited list of the names of the fields on the form.

Example

<!--- This example shows the use of ArrayAvg --->
<!-- The following lines of code keep track of the form fields that can
be dynamically generated on the screen. It uses the Fieldnames variable
with the ListLen function to determine the number of fields on the form. --->
<cfset FormElem = 2>
   <cfif Isdefined("Form.Submit")>
      <cfif Form.Submit is "More">
         <cfset FormElem = ListLen(Form.Fieldnames)>
      </cfif>
   </cfif>

<html>
<head>
<title>ArrayAvg Example</title>
</head>
<body>
<h3>ArrayAvg Example</h3>
<p> This example uses ArrayAvg to find the average of the numbers that you enter
into an array.<br>
To enter more than two numbers press the <b>more</b> button.
</p>
<form action = "arrayavg.cfm">
<!--- The following code initially creates two fields. It adds fields if the user
presses MORE. FormElem is initialized to two at the beginning of this
code to show that the form has two fields. ----->
<input type = "submit" name = "submit" value = "more">
<table cellspacing = "2" cellpadding = "2" border = "0">
<cfloop index = "LoopItem" from = "1" to = "#FormElem#">
   <tr>
      <cfoutput>
        <th align = "left">Number #LoopItem#</th>
        <td><input type = "text" name = "number#LoopItem#"></td>
      </cfoutput>
   </tr>
</cfloop>
</table>
<input type = "submit" name = "submit" value = "get the average">
</form>

<!--- create an array --->
<cfif IsDefined("FORM.submit")>
   <cfset myNumberArray = ArrayNew(1)>
   <cfset Count = 1>
   <cfloop index = "ListItem" list = "#Form.Fieldnames#">
       <cfif Left(ListItem,3) is "Num">
         <cfset myNumberArray[Count] = Val(Evaluate("number#Count#"))>
         <cfset count = IncrementValue(Count)>
      </cfif>
   </cfloop>

   <cfif Form.Submit is "get the average">
      <!--- use ArrayAvg to get the average of the two numbers --->
      <p>The average of the numbers that you entered is
      <cfoutput>#ArrayAvg(myNumberArray)#.</cfoutput>
   <cfelse>
      <cfoutput>Try again. You must enter at least two numeric values.
      </cfoutput>
   </cfif>
</cfif>
</body>
</html>


ArrayClear

Description

Deletes the data in an array.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayClear(array)

See also

ArrayDeleteAt

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArrayClear Example</h3>
<!--- create a new array --->
<cfset MyArray = ArrayNew(1)>
<!--- populate an element or two --->
<cfset MyArray[1] = "Test">
<cfset MyArray[2] = "Other Test">
<!--- output the contents of the array --->
<p>Your array contents are:
<cfoutput>#ArrayToList(MyArray)#</cfoutput>
<!--- check if the array is empty --->
<p>Is the array empty?:
<cfoutput>#ArrayIsEmpty(MyArray)#</cfoutput>
<p>Now, clear the array:
<!--- now clear the array --->
<cfset Temp = ArrayClear(MyArray)>
<!--- check if the array is empty --->
<p>Is the array empty?:
<cfoutput>#ArrayIsEmpty(MyArray)#</cfoutput>


ArrayDeleteAt

Description

Deletes an element from an array.

When an element is deleted, ColdFusion recalculates index positions. For example, in an array that contains the months of the year, deleting the element at position 5 removes the entry for May. After this, to delete the entry for June, you would delete the element at position 5 (not 6).

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayDeleteAt(array, position)

See also

ArrayInsertAt

History

New in ColdFusion MX: this function can be used on XML objects.

New in ColdFusion MX: this function can throw the InvalidArrayIndexException error.

Parameters

Parameter | Description
array | Name of an array
position | Array position

Throws

If this function attempts to delete an element at position 0, or specifies a value for position that is greater than the size of array, this function throws an InvalidArrayIndexException error.

Example

<h3>ArrayDeleteAt Example</h3><p>
<!--- create an array --->
<cfset DaysArray = ArrayNew(1)>
<!--- populate an element or two --->
<cfset DaysArray[1] = "Monday">
<cfset DaysArray[2] = "Tuesday">
<cfset DaysArray[3] = "Wednesday">
<!--- delete the second element --->
<p>Is the second element gone?:
 <cfoutput>#ArrayDeleteAt(DaysArray,2)#</cfoutput>
<!--- the formerly third element, "Wednesday" is second element --->
<p>The second element is now: <cfoutput>#DaysArray[2]#</cfoutput>


ArrayInsertAt

Description

Inserts a value into an array. Array elements whose indexes are greater than the new position are incremented by one. The array length increases by one.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayInsertAt(array, position, value)

See also

ArrayDeleteAt

History

New in ColdFusion MX: this function can be used on XML objects.

New in ColdFusion MX: this function can throw the InvalidArrayIndexException error.

Parameters

Parameter | Description
array | Name of an array
position | Index position at which to insert value
value | Value to insert

Throws

If this function attempts to insert an element at position 0, or specifies a value for position that is greater than the size of array, this function throws an InvalidArrayIndexException error.

Example

<h3>ArrayInsertAt Example</h3><p>
<!--- create a new array --->
<cfset DaysArray = ArrayNew(1)>
<!--- populate an element or two --->
<cfset DaysArray[1] = "Monday">
<cfset DaysArray[2] = "Tuesday">
<cfset DaysArray[3] = "Thursday">
<!--- add an element before position 3 --->
<p>Add an element before position 3:
   <cfoutput>#ArrayInsertAt(DaysArray,3,"Wednesday")#</cfoutput>
<p>Now output the array as a list:
<cfoutput>#ArrayToList(DaysArray)#</cfoutput>
<!--- The array now has four elements. Element 3, "Thursday", has become element
four --->


ArrayIsEmpty

Description

Determines whether an array is empty of data elements.

Return value

True, if the array is empty; otherwise, False.

Category

Array functions

Syntax

ArrayIsEmpty(array)

See also

ArrayLen

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArrayIsEmpty Example</h3>
<!--- create a new array --->
<cfset MyArray = ArrayNew(1)>
<!--- populate an element or two --->
<cfset MyArray[1] = "Test">
<cfset MyArray[2] = "Other Test">
<!--- output the contents of the array --->
<p>Your array contents are:
<cfoutput>#ArrayToList(MyArray)#</cfoutput>
<!--- check if the array is empty --->
<p>Is the array empty?:
<cfoutput>#ArrayIsEmpty(MyArray)#</cfoutput>
<p>Now, clear the array:
<!--- now clear the array --->
<cfset Temp = ArrayClear(MyArray)>
<!--- check if the array is empty --->
<p>Is the array empty?:
<cfoutput>#ArrayIsEmpty(MyArray)#</cfoutput>


ArrayLen

Description

Determines the number of elements in an array.

Return value

The number of elements in an array.

Category

Array functions

Syntax

ArrayLen(array)

See also

ArrayIsEmpty

History

New in ColdFusion MX: this function can be used on child XML objects.

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArrayLen Example</h3>
<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
SELECT FirstName, LastName FROM Employees
</cfquery>
<!--- create an array --->
<cfset myArray = ArrayNew(1)>
<!--- set element one to show where we are --->
<cfset myArray[1] = "Test Value">
<!--- loop through the query and append these names
successively to the last element --->
<cfloop query = "GetEmployeeNames">
   <cfset temp = ArrayAppend(myArray, "#FirstName# #LastName#")>
</cfloop>
<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>
<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the array are as follows:
   <p>#myList#
   <p>This array has #ArrayLen(MyArray)# elements.
</cfoutput>


ArrayMax

Description

Array maximum function.

Return value

The largest numeric value in an array. If the array parameter value is an empty array, returns zero.

Category

Array functions

Syntax

ArrayMax(array)

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArrayMax Example</h3>
<p>This example uses ArrayMax to find the largest number in an array.<br> </p>
<!--- After checking whether the form has been submitted, the code creates an array
and assigns the form fields to the first two elements in the array. ---->
<cfif IsDefined("FORM.submit")>
   <cfset myNumberArray = ArrayNew(1)>
   <cfset myNumberArray[1] = number1>
   <cfset myNumberArray[2] = number2>
   <cfif Form.Submit is "Maximum Value">
      <!--- use ArrayMax to find the largest number in the array --->
      <p>The largest number that you entered is
      <cfoutput>#ArrayMax(myNumberArray)#.</cfoutput>
   </cfif>
</cfif>
<!---- The following form provides two numeric fields that are compared when the
form is submitted. --->
<form action = "arraymax.cfm">
<input type = "hidden" name = "number1_Float">
<input type = "hidden" name = "number2_Float">
<input type = "text" name = "number1"><br>
<input type = "text" name = "number2"><br>
<input type = "submit" name = "submit" value = "Maximum Value">
</form>


ArrayMin

Description

Array minimum function.

Return value

The smallest numeric value in an array. If the array parameter value is an empty array, returns zero.

Category

Array functions

Syntax

ArrayMin(array)

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArrayMin Example</h3>
<p>This example uses ArrayMin to find the smallest number in an array.<br></p>
<!--- After checking whether the form has been submitted, this code creates an
array and assigns the form fields to the first two elements. ----->
<cfif IsDefined("FORM.submit")>
   <cfset myNumberArray = ArrayNew(1)>
   <cfset myNumberArray[1] = FORM.number1>
   <cfset myNumberArray[2] = FORM.number2>

   <cfif Form.Submit is "Minimum Value">
      <!--- use ArrayMin to find the smallest number in the array --->
      <p>The smallest number that you entered is
      <cfoutput>#ArrayMin(myNumberArray)#.</cfoutput>
   </cfif>
</cfif>
<!---- The following form provides two numeric fields that are compared when the
form is submitted. ----->
<form action = "arraymin.cfm">
<input type = "hidden" name = "number1_Float">
<input type = "hidden" name = "number2_Float">
<input type = "text" name = "number1"><br>
<input type = "text" name = "number2"><br>
<input type = "submit" name = "submit" value = "Minimum Value">
</form>


ArrayNew

Description

Creates an array of 1–3 dimensions. Index array elements with square brackets: [ ].

ColdFusion arrays expand dynamically as data is added.

Return value

An array

Category

Array functions

Syntax

ArrayNew(dimension)

Parameters

Parameter | Description
dimension | Number of dimensions in new array. 1, 2, or 3

Example

<h3>ArrayNew Example</h3>
<!--- Make an array --->
<cfset MyNewArray = ArrayNew(1)>
<!--- ArrayToList does not function properly if the Array is not initialized with
ArraySet --->
<cfset temp = ArraySet(MyNewArray, 1,6, "")>

<!--- set some elements --->
<cfset MyNewArray[1] = "Sample Value">
<cfset MyNewArray[3] = "43">
<cfset MyNewArray[6] = "Another Value">

<!--- is it an array? --->
<cfoutput>
   <p>Is this an array? #IsArray(MyNewArray)#
   <p>It has #ArrayLen(MyNewArray)# elements.
   <p>Contents: #ArrayToList(MyNewArray)#
<!--- the array has expanded dynamically to six elements with the use of ArraySet,
even though we only set three values --->
</cfoutput>


ArrayPrepend

Description

Inserts an array element at the beginning of an array.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayPrepend(array, value)

See also

ArrayAppend

Parameters

Parameter | Description
array | Name of an array
value | Value to insert at beginning of array

Example

<h3>ArrayPrepend Example</h3>
<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
   SELECT FirstName, LastName FROM Employees
</cfquery>
<!--- create an array --->
<cfset myArray = ArrayNew(1)>
<!--- set element one to show where we are --->
<cfset myArray[1] = "Test Value">
<!--- loop through query. Append names successively before last element (list
reverses itself from the standard queried output, as it keeps
prepending the array entry) --->
<cfloop query = "GetEmployeeNames">
   <cfoutput>#ArrayPrepend(myArray, "#FirstName# #LastName#")#
   </cfoutput>, Array was prepended<br>
</cfloop>
<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>
<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the array are as follows:
   <p>#myList#
</cfoutput>


ArrayResize

Description

Resets an array to a specified minimum number of elements. This can improve performance, if used to size an array to its expected maximum. For more than 500 elements, use ArrayResize immediately after using the ArrayNew tag.

ColdFusion arrays expand dynamically as data is added.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArrayResize(array, minimum_size)

Parameters

Parameter | Description
array | Name of an array
minimum_size | Minimum array size

Example

<h3>ArrayResize Example</h3>
<!--- perform a query to get the list --->
<cfquery name = "GetCourses" datasource = "cfsnippets">
SELECT * FROM Courses
</cfquery>
<!--- make a new array --->
<cfset MyArray = ArrayNew(1)>
<!--- resize that array to the number of records
in the query --->
<cfset temp = ArrayResize(MyArray, GetCourses.RecordCount)>
<cfoutput>
The array is now #ArrayLen(MyArray)# elements, to match
the query of #GetCourses.RecordCount# records.
</cfoutput>


ArraySet

Description

In a one-dimensional array, sets the elements in a specified index range to a value. Useful for initializing an array after a call to ArrayNew.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArraySet(array, start_pos, end_pos, value)

See also

ArrayNew

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
array | Name of an array.
start_pos | Starting index position of range to set.
end_pos | Ending index position of range to set. If this value is greater than array length, ColdFusion adds elements to array.
value | Value to which to set each element in the range.

Example

<h3>ArraySet Example</h3>

<!--- Make an array --->
<cfset MyNewArray = ArrayNew(1)>
<!--- ArrayToList does not function properly if the Array has not been initialized
with ArraySet --->
<cfset temp = ArraySet(MyNewArray, 1,6, "Initial Value")>

<!--- set some elements --->
<cfset MyNewArray[1] = "Sample Value">
<cfset MyNewArray[3] = "43">
<cfset MyNewArray[6] = "Another Value">
...


ArraySort

Description

Sorts array elements numerically or alphanumerically.

Return value

True, if sort is successful; False, otherwise.

Category

Array functions , List functions

Syntax

ArraySort(array, sort_type [, sort_order ])

History

New in ColdFusion MX: this function can throw the ArraySortSimpleValueException error and ValueNotNumeric error.

New in ColdFusion MX: in a textnocase, descending sort, this function might return elements in a different sort order than in earlier releases. If sort_type = "textnocase" and sort_order = "desc", ColdFusion MX processes elements that differ only in case differently from earlier releases, as follows:

  • ColdFusion MX reverses the elements’ original order
  • Earlier releases of ColdFusion do not change the elements’ original order

For example, in a textnocase, desc sort of d,a,a,b,A, the following occurs:

  • ColdFusion MX returns d,b,A,a,a
  • Earlier ColdFusion releases return d,b,a,a,A

(In a textnocase, asc sort, all ColdFusion releases return a,a,A,b,d.)

Parameters

Parameter
Description
  • array
  • Name of an array
  • sort_type
  • numeric: sorts numbers
  • text: sorts text alphabetically, taking case into account (also known as case sensitive). All letters of one case precede the first letter of the other case:
    • - aabzABZ, if sort_order = "asc" (ascending sort)
    - ZBAzbaa, if sort_order = "desc" (descending sort)
  • textnocase: sorts text alphabetically, without regard to case (also known as case-insensitive). A letter in varying cases precedes the next letter:
    • - aAaBbBzzZ, in an ascending sort; preserves original intra-letter order
    - ZzzBbBaAa, in a descending sort; reverses original intra-letter order
  • sort_order
  • asc - ascending sort order. Default.
    • - aabzABZ or aAaBbBzzZ, depending on value of sort_type, for letters
    - from smaller to larger, for numbers
  • desc - descending sort order.
    • - ZBAzbaa or ZzzBbBaAa, depending on value of sort_type, for letters
    - from larger to smaller, for numbers

Throws

If an array element is other than a simple element, this function throws an ArraySortSimpleValueException error. If sort_type is numeric and an array element is not numeric, this function throws a ValueNotNumeric error.

Example

<!--- This example shows ArraySort --->
<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
SELECT FirstName, LastName FROM Employees
</cfquery>
<!--- create an array --->
<cfset myArray = ArrayNew(1)>
<!--- loop through the query and append these names successively to the last
element --->
<cfloop query = "GetEmployeeNames">
   <cfset temp = ArrayAppend(myArray, "#FirstName# #LastName#")>
</cfloop>
<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>
<!--- sort that array descending alphabetically --->
<cfset isSuccessful = ArraySort(myArray, "textnocase", "desc")>
...


ArraySum

Description

Array sum function.

Return value

The sum of values in an array. If the array parameter value is an empty array, returns zero.

Category

Array functions , Mathematical functions

Syntax

ArraySum(array)

Parameters

Parameter | Description
array | Name of an array

Example

<h3>ArraySum Example</h3>
<p>This example uses ArraySum to add two numbers together.<br> </p>
<!--- After checking whether the form has been submitted, the code creates
an array and assigns the form fields to the first two elements in
the array. --->
<cfif IsDefined("FORM.submit")>
   <cfset myNumberArray = ArrayNew(1)>
   <cfset myNumberArray[1] = number1>
   <cfset myNumberArray[2] = number2>

   <cfif Form.Submit is "Add">
      <!--- use ArraySum to add the number in the array --->
      <p>The sum of the numbers is
      <cfoutput>#ArraySum(myNumberArray)#.</cfoutput>
   </cfif>
</cfif>
<!--- This form provides two numeric fields that are added when the form is
submitted. --->
<form action = "arraysum.cfm" method="post">
   <input type = "hidden" name = "number1_Float">
   <input type = "hidden" name = "number2_Float">
   <input type = "text" name = "number1">
   <br>
   <input type = "text" name = "number2">
   <br>
   <input type = "submit" name = "submit" value = "Add">
</form>


ArraySwap

Description

Swaps array values of an array at specified positions. This function is more efficient than multiple cfset tags.

Return value

True, on successful completion.

Category

Array functions

Syntax

ArraySwap(array, position1, position2)

Parameters

Parameter | Description
array | Name of an array
position1 | Position of first element to swap
position2 | Position of second element to swap

Example

<h3>ArraySwap Example</h3>

<cfset month = ArrayNew(1)>
<cfset month[1] = "February">
<cfset month[2] = "January">
<cfset temp = ArraySwap(month, 1, 2)>
<cfset temp = ArrayToList(month)>

<p>Show the results: <cfoutput>#temp#</cfoutput>


ArrayToList

Description

Converts a one-dimensional array to a list.

Return value

Delimited list, as a string.

Category

Array functions, Conversion functions, List functions

Syntax

ArrayToList(array [, delimiter ])

Parameters

Parameter | Description
array | Name of array
delimiter | Character to separate list elements. Default: comma. ColdFusion uses only the first character of this parameter.

Example

<h3>ArrayToList Example</h3>
<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
SELECT FirstName, LastName FROM Employees
</cfquery>
<!--- create an array --->
<cfset myArray = ArrayNew(1)>
<!--- loop through query, append names successively to last element --->
<cfloop query = "GetEmployeeNames">
   <cfset temp = ArrayAppend(myArray, "#FirstName# #LastName#")>
</cfloop>
<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>
<!--- sort that array descending alphabetically --->
<cfset myAlphaArray = ArraySort(myArray, "textnocase", "desc")>
<!--- show the resulting alphabetized array as a list --->
<cfset myAlphaList = ArrayToList(myArray, ",")>
<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the array are as follows:
   <p>#myList#
   <p>This array, alphabetized by first name (descending):
   <p>#myAlphaList#
   <p>This array has #ArrayLen(MyArray)# elements.
</cfoutput>


Asc

Description

Determines the value of a character.

Return value

The value of the first character of a string; if string is empty, returns zero.

Category

String functions

Syntax

Asc(string)

See also

Chr

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode characters, up to a value of 65536. (Earlier releases supported 1-255.)

Parameters

Parameter | Description
string | A string

Example

<h3>Asc Example</h3>
<!--- if the character string is not empty, output its ASCII value --->
<cfif IsDefined("FORM.charVals")>

   <cfif FORM.charVals is not "">
      <cfoutput>#Left(FORM.charVals,1)# =
     #Asc(FORM.charVals)#</cfoutput>
   <cfelse>
<!--- if it is empty, output an error message --->
      <h4>Enter a character</h4>
   </cfif>
</cfif>

<form action = "asc.cfm">
<p>Enter a character to see its ASCII value
<br><input type = "Text" name = "CharVals" size = "1" MAXLENGTH = "1">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


ASin

Description

Determines the arcsine of a number. The arcsine is the angle whose sine is number.

Return value

The arcsine of a number, in radians.

Category

Mathematical functions

Syntax

ASin(number)

See also

Sin , Cos , Pi , Tan

Parameters

Parameter | Description
number | Sine of an angle. The value must be between -1 and 1, inclusive.

Usage

The range of the result is -p/2 to p/2 radians. To convert degrees to radians, multiply degrees by p/180. To convert radians to degrees, multiply radians by 180/p.

Example

<h3>ASin Example</h3>
<!--- output its arcsine value --->
<cfif IsDefined("FORM.SinNum")>
   <cfif IsNumeric(FORM.SinNum)>
      <cfif FORM.SinNum LESS THAN OR EQUAL TO 1>
         <cfif FORM.SinNum GREATER THAN OR EQUAL TO -1>
            ASin(<cfoutput>#FORM.SinNum#</cfoutput>) =
             <cfoutput>#Evaluate(ASin(FORM.sinNum))# Radians</cfoutput>
             <br> or <br>ASin(<cfoutput>#FORM.SinNum#</cfoutput>) =
            <cfoutput>
               #Evaluate(ASin(FORM.sinNum) * 180/Pi())# Degrees
            </cfoutput>
         <cfelse>
<!--- if it is less than negative one, output an error message --->
            <h4>Enter the sine of the angle to calculate, in degrees and radians.
            The value must be between 1 and -1, inclusive.</h4>
         </cfif>
      <cfelse>
<!--- if it is greater than one, output an error message --->
      <h4>Enter the sine of the angle to calculate, in degrees and radians. The
value must be between 1 and -1, inclusive.</h4>
      </cfif>
   <cfelse>
<!--- if it is empty, output an error message --->
      <h4>Enter the sine of the angle to calculate, in degrees and radians. The
value must be between 1 and -1,inclusive.</h4>
   </cfif>
</cfif>
<form action = "asin.cfm">
<p>Enter a number to get its arcsine in Radians and Degrees.
<br><input type = "Text" name = "sinNum" size = "25">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


Atn

Description

Arctangent function. The arctangent is the angle whose tangent is number.

Return value

The arctangent of a number.

Category

Mathematical functions

Syntax

Atn(number)

See also

Tan , Sin , Cos , Pi

Parameters

Parameter | Description
number | Tangent of an angle

Usage

The range of the result is -p/2 to p/2 radians. To convert degrees to radians, multiply degrees by p/180. To convert radians to degrees, multiply radians by 180/p.

Example

<h3>Atn Example</h3>
<!--- output its Atn value --->
<cfif IsDefined("FORM.AtnNum")>
   <cfif IsNumeric(FORM.AtnNum)>
      Atn(<cfoutput>#FORM.AtnNum#</cfoutput>) =
     <cfoutput>#Atn(FORM.AtnNum)# radians =
      #Evaluate(Atn(FORM.AtnNum * 180/PI())#
       Degrees</cfoutput>
   <cfelse>
<!--- if it is empty, output an error message --->
      <h4>Enter a number</h4>
   </cfif>
</cfif>
<form action = "atn.cfm">
<p>Enter a number to get its arctangent in Radians and Degrees
<br><input type = "Text" name = "atnNum" size = "25">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


AuthenticatedContext

Description

This function is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML.

History

New in ColdFusion MX: This function is obsolete. It does not work in ColdFusion MX and later ColdFusion releases.


AuthenticatedUser

Description

This function is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML.

History

New in ColdFusion MX: This function is obsolete. It does not work in ColdFusion MX and later ColdFusion releases.


BitAnd

Description

Performs a bitwise logical AND operation.

Return value

The bitwise AND of two long integers.

Category

Mathematical functions

Syntax

BitAnd(number1, number2)

See also

BitNot , BitOr , BitXor

Parameters

Parameter | Description
number1 | 32-bit signed integer
number2 | 32-bit signed integer

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitAnd Example</h3>

<p>Returns the bitwise AND of two long integers.
<p>BitAnd(5,255): <cfoutput>#BitAnd(5,255)#</cfoutput>
<p>BitAnd(5,0): <cfoutput>#BitAnd(5,0)#</cfoutput>
<p>BitAnd(128,128): <cfoutput>#BitAnd(128,128)#</cfoutput>


BitMaskClear

Description

Performs a bitwise mask clear operation.

Return value

A number, bitwise cleared, with length bits beginning at start.

Category

Mathematical functions

Syntax

BitMaskClear(number, start, length)

See also

BitMaskRead , BitMaskSet

Parameters

Parameter | Description
number | 32-bit signed integer
start | Integer, in the range 0-31, inclusive; start bit for mask
length | Integer, in the range 0-31, inclusive; length of mask

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitMaskClear Example</h3>

<p>Returns number bitwise cleared with length bits beginning from start.

<p>BitMaskClear(255, 4, 4): <cfoutput>#BitMaskClear(255, 4, 4)#
</cfoutput>
<p>BitMaskClear(255, 0, 4): <cfoutput>#BitMaskClear(255, 0, 4)#
</cfoutput>
<p>BitMaskClear(128, 0, 7): <cfoutput>#BitMaskClear(128, 0, 7)#
</cfoutput>


BitMaskRead

Description

Performs a bitwise mask read operation.

Return value

An integer, created from length bits of number, beginning at start.

Category

Mathematical functions

Syntax

BitMaskRead(number, start, length)

See also

BitMaskClear , BitMaskSet

Parameters

Parameter | Description
number | 32-bit signed integer to mask
start | Integer, in the range 0-31, inclusive; start bit for read
length | Integer, in the range 0-31, inclusive; length of mask

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitMaskRead Example</h3>
<p>Returns integer created from <em>length</em> bits of <em>number</em>, beginning
with <em>start</em>.

<p>BitMaskRead(255, 4, 4): <cfoutput>#BitMaskRead(255, 4, 4)#
</cfoutput>
<p>BitMaskRead(255, 0, 4): <cfoutput>#BitMaskRead(255, 0, 4)#
</cfoutput>
<p>BitMaskRead(128, 0, 7): <cfoutput>#BitMaskRead(128, 0, 7)#
</cfoutput>


BitMaskSet

Description

Performs a bitwise mask set operation.

Return value

A number, bitwise masked with length bits of mask beginning at start.

Category

Mathematical functions

Syntax

BitMaskSet(number, mask, start, length)

See also

BitMaskClear , BitMaskRead

Parameters

Parameter | Description
number | 32-bit signed integer
mask | 32-bit signed integer; mask
start | Integer, in the range 0-31, inclusive; start bit for mask
length | Integer, in the range 0-31, inclusive; length of mask

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitMaskSet Example</h3>
<p>Returns number bitwise masked with length bits of mask beginning at start.

<p>BitMaskSet(255, 255, 4, 4):
<cfoutput>#BitMaskSet(255, 255, 4, 4)#</cfoutput>
<p>BitMaskSet(255, 0, 4, 4):
<cfoutput>#BitMaskSet(255, 0, 4, 4)#</cfoutput>
<p>BitMaskSet(0, 15, 4, 4):
<cfoutput>#BitMaskSet(0, 15, 4, 4)#</cfoutput>


BitNot

Description

Performs a bitwise logical NOT operation.

Return value

A number; the bitwise NOT of a long integer.

Category

Mathematical functions

Syntax

BitNot(number)

See also

BitAnd , BitOr , BitXor

Parameters

Parameter | Description
number | 32-bit signed integer

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitNot Example</h3>
<p>Returns the bitwise NOT of a long integer.

<p>BitNot(0): <cfoutput>#BitNot(0)#</cfoutput>
<p>BitNot(255): <cfoutput>#BitNot(255)#</cfoutput>


BitOr

Description

Performs a bitwise logical OR operation.

Return value

A number; the bitwise OR of two long integers.

Category

Mathematical functions

Syntax

BitOr(number1, number2)

See also

BitAnd , BitNot , BitXor

Parameters

Parameter | Description
number1 | 32-bit signed integer
number2 | 32-bit signed integer

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitOr Example</h3>
<p>Returns the bitwise OR of two long integers.

<p>BitOr(5,255): <cfoutput>#BitOr(5,255)#</cfoutput>
<p>BitOr(5,0): <cfoutput>#BitOr(5,0)#</cfoutput>
<p>BitOr(7,8): <cfoutput>#BitOr(7,8)#</cfoutput>


BitSHLN

Description

Performs a bitwise shift-left, no-rotation operation.

Return value

A number, bitwise shifted without rotation to the left by count bits.

Category

Mathematical functions

Syntax

BitSHLN(number, count)

See also

BitSHRN

Parameters

Parameter | Description
number | 32-bit signed integer
count | Integer, in the range 0-31, inclusive; number of bits to shift the number

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitSHLN Example</h3>
<p>Returns the number, bitwise shifted, without rotation, to the left by count
bits.

<p>BitSHLN(1,1): <cfoutput>#BitSHLN(1,1)#</cfoutput>
<p>BitSHLN(1,30): <cfoutput>#BitSHLN(1,30)#</cfoutput>
<p>BitSHLN(1,31): <cfoutput>#BitSHLN(1,31)#</cfoutput>
<p>BitSHLN(2,31): <cfoutput>#BitSHLN(2,31)#</cfoutput>


BitSHRN

Description

Performs a bitwise shift-right, no-rotation operation.

Return value

A number, bitwise shifted, without rotation, to the right by count bits.

Category

Mathematical functions

Syntax

BitSHRN(number, count)

See also

BitSHLN

Parameters

Parameter | Description
number | 32-bit signed integer
count | Integer, in the range 0-31, inclusive. Number of bits to shift the number

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitSHRN Example</h3>
<p>Returns a number, bitwise shifted, without rotation, to the right, by count
bits.

<p>BitSHRN(1,1): <cfoutput>#BitSHRN(1,1)#</cfoutput>
<p>BitSHRN(255,7): <cfoutput>#BitSHRN(255,7)#</cfoutput>
<p>BitSHRN(-2147483548,1): <cfoutput>#BitSHRN(-2147483548,1)#
</cfoutput>


BitXor

Description

Performs a bitwise logical XOR operation.

Return value

Bitwise XOR of two long integers.

Category

Mathematical functions

Syntax

BitXor(number1, number2)

See also

BitAnd , BitNot , BitOr

Parameters

Parameter | Description
number1 | 32-bit signed integer
number2 | 32-bit signed integer

Usage

Bit functions operate on 32-bit signed integers, in the range -2147483648 – 2147483647.

Example

<h3>BitXOr Example</h3>
<p>Returns the bitwise XOR of two long integers.

<p>BitXOr(5,255): <cfoutput>#BitXOr(5,255)#</cfoutput>
<p>BitXOr(5,0): <cfoutput>#BitXOr(5,0)#</cfoutput>
<p>BitXOr(128,128): <cfoutput>#BitXOr(128,128)#</cfoutput>


Ceiling

Description

Determines the closest integer that is greater than a specified number.

Return value

The closest integer that is greater than a given number.

Category

Mathematical functions

Syntax

Ceiling(number)

See also

Int , Fix , Round

Parameters

Parameter | Description
number | A real number

Example

<h3>Ceiling Example</h3>

<cfoutput>
<p>The ceiling of 3.4 is #ceiling(3.4)#
<p>The ceiling of 3 is #ceiling(3)#
<p>The ceiling of 3.8 is #ceiling(3.8)#
<p>The ceiling of -4.2 is #ceiling(-4.2)#
</cfoutput>


Chr

Description

ASCII Character function.

Return value

A character, of the given ASCII character code.

Category

String functions

Syntax

Chr(number)

See also

Asc

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode characters, up to a value of 65536. (Earlier releases supported 1-255.)

Parameters

Parameter | Description
number | A value (a number in the range 0 to 255, inclusive)

Usage

The values 0 – 31 are standard, nonprintable codes. For example:

  • Chr(10) returns a linefeed character
  • Chr(13) returns a carriage return character
  • The two-character string Chr(13) & Chr(10) returns a newline

Example

<h3>CHR Example</h3>
<!--- if the character string is not empty, output its CHR value --->
<cfif IsDefined("FORM.Submit")>
   <cfoutput>#FORM.charVals# = #CHR(FORM.charVals)#</cfoutput>
</cfif>
<form action = "chr.cfm">
<p>Enter a number between 1 and 256 to see the ASCII representation.
<input type = "hidden" name = "CharVals_range" Value = "Min = 1 Max = 256">
<input type = "hidden" name = "CharVals_required" Value = "Enter an integer from 1
to 256">
<br><input type = "Text" name = "CharVals">
<p><input type = "Submit" name = "Submit"> <input type = "RESET">
</form>


CJustify

Description

Centers a string in a field length.

Return value

String, center-justified. If length is less than the length of the string, the string is returned unchanged.

Category

Display and formatting functions, String functions

Syntax

Cjustify(string, length)

See also

LJustify , RJustify

Parameters

Parameter
Description
string
A string or a variable that contains one. May be empty. If it is a variable that is defined as a number, the function processes it as a string.
length
A positive integer or a variable that contains one. Length of field.
Can be coded as:
  • A number; for example, 6
  • A string representation of a number; for example, "6"
Any other value causes ColdFusion to throw an error.

Example

<!--- This example shows how to use CJustify --->
<CFPARAM name = "jstring" DEFAULT = "">

<cfif IsDefined("FORM.justifyString")>
   <cfset jstring = Cjustify("#FORM.justifyString#", 35)>
</cfif>
<html>
<head>
<title>CJustify Example</title>
</head>
<body>
<h3>CJustify</h3>
<p>Enter a string; it will be center-justified within the sample field.
<form action = "cjustify.cfm">
<p><input type = "Text" value = "<cfoutput>#jString#</cfoutput>"
      size = 35 name = "justifyString">
<p><input type = "Submit" name = "">
<input type = "RESET">
</form>
</body>
</html>


Compare

Description

Performs a case-sensitive comparison of two strings.

Return value

  • -1, if string1 is less than string2
  • 0, if string1 is equal to string2
  • 1, if string1 is greater than string2

Category

String functions

Syntax

Compare(string1, string2)

See also

CompareNoCase , Find

Parameters

Parameter | Description
string1 | A string or a variable that contains one
string2 | A string or a variable that contains one

Usage

Compares the values of corresponding characters in string1 and string2.

Example

<h3>Compare Example</h3>
<p>The compare function performs a <I>case-sensitive</I> comparison of two strings.

<cfif IsDefined("FORM.string1")>
 <cfset comparison = Compare(FORM.string1, FORM.string2)>
 <!--- switch on the variable to give various responses --->
 <cfswitch expression = #comparison#>
   <cfcase value = "-1">
      <h3>String 1 is less than String 2</h3>
      <I>The strings are not equal</I>
   </cfcase>
   <cfcase value = "0">
      <h3>String 1 is equal to String 2</h3>
      <I>The strings are equal!</I>
   </cfcase>
   <cfcase value = "1">
      <h3>String 1 is greater than String 2</h3>
      <I>The strings are not equal</I>
   </cfcase>
   <CFDEFAULTCASE>
      <h3>This is the default case</h3>
   </CFDEFAULTCASE>
   </cfswitch>
</cfif>

<form action = "compare.cfm">
<p>String 1
<br><input type = "Text" name = "string1">

<p>String 2
<br><input type = "Text" name = "string2">
<p><input type = "Submit" value = "Compare these Strings" name = "">
   <input type = "RESET">
</form>


CompareNoCase

Description

Performs a case-insensitive comparison of two strings.

Return value

An indicator of the difference:

  • A negative number, if string1 is less than string2
  • 0, if string1 is equal to string2
  • A positive number, if string1 is greater than string2

Category

String functions

Syntax

CompareNoCase(string1, string2)

See also

Compare , FindNoCase

Parameters

Parameter | Description
string1 | A string or a variable that contains one
string2 | A string or a variable that contains one

Example

<H3>CompareNoCase Example</H3>
<P>This function performs a <I>case-insensitive</I> comparison of two strings.
<CFIF IsDefined("form.string1")>
<CFSET comparison = Comparenocase(form.string1, form.string2)>
<!--- switch on the variable to give various responses --->
<CFSWITCH EXPRESSION=#comparison#>
   <CFCASE value="-1">
      <H3>String 1 is less than String 2</H3>
      <I>The strings are not equal</I>
   </CFCASE>
   <CFCASE value="0">
      <H3>String 1 is equal to String 2</H3>
      <I>The strings are equal!</I>
   </CFCASE>
   <CFCASE value="1">
      <H3>String 1 is greater than String 2</H3>
      <I>The strings are not equal</I>
   </CFCASE>
   <CFDEFAULTCASE>
      <H3>This is the default case</H3>
   </CFDEFAULTCASE>
</CFSWITCH>
</CFIF>
<FORM ACTION="comparenocase.cfm" METHOD="POST">
<P>String 1
<BR><INPUT TYPE="Text" NAME="string1">
<P>String 2
<BR><INPUT TYPE="Text" NAME="string2">
<P><INPUT TYPE="Submit" VALUE="Compare these Strings" NAME="">
<INPUT TYPE="RESET">
</FORM>


Cos

Description

Cosine function.

Return value

The cosine of an angle, in radians.

Category

Mathematical functions

Syntax

Cos(number)

See also

Sin , Tan , Pi

Parameters

Parameter | Description
number | Angle, in radians, for which to calculate the cosine

Usage

The range of the result is -1 to 1.

To convert degrees to radians, multiply degrees by p/180. To convert radians to degrees, multiply radians by 180/p.

Example

<h3>Cos Example</h3>
<!--- output its Cos value --->
<cfif IsDefined("FORM.CosNum")>
   <cfif IsNumeric(#FORM.CosNum#)>
      Cos(<cfoutput>#FORM.CosNum#</cfoutput>) =
      <cfoutput>#Cos(FORM.cosNum)#
      radians = #Evaluate(Cos(FORM.cosNum) * 180/PI())#
      Degrees</cfoutput>
   <cfelse>
<!--- if it is empty, output an error message --->
      <h4>Enter a number between -1 and 1</h4>
   </cfif>
</cfif>
<form action = "cos.cfm" method="post">
<p>Enter a number to get its cosine in Radians and Degrees
<br><input type = "Text" name = "cosNum" size = "25">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


CreateDate

Description

Creates a date/time object.

Return value

A date/time value.

Category

Date and time functions

Syntax

CreateDate(year, month, day)

See also

CreateDateTime , CreateODBCDate

Parameters

Parameter | Description
year | Integer, in the range 0-9999. See How ColdFusion processes two-digit year values.
month | Number in the range 1 (January) - 12 (December)
day | Number in the range 1 - 31

Usage

CreateDate is a subset of CreateDateTime.

The time in the returned object is set to 00:00:00.


How ColdFusion processes two-digit year values

For most locales, if the year part of a date string uses the abbreviated pattern "y" or "yy", it is interpreted relative to a century, by adjusting dates to within 80 years before and 20 years after the date instance is created.

For example, if the pattern is "mm/dd/yy", and a date instance is created on Jan 1, 1997, the string "01/11/12" is interpreted as Jan 11, 2012. The string "05/04/64" is interpreted as May 4, 1964.

For the following locales, the algorithm is similar, but the adjustment is made to within 72 years before and 28 years after the date instance is created:

  • English (Australian)
  • English (New Zealand)
  • German (Austrian)
  • German (Standard)
  • German (Swiss)
  • Portuguese (Brazilian)
  • Portuguese (Standard)
  • Swedish

This applies to the Sun JRE Version 1.4 and the IBM JRE Version 1.3.0.

Example

<h3>CreateDate Example</h3>
<CFIF IsDefined("form.year")>
<p>Your date value, generated with CreateDate:
<CFSET yourDate = CreateDate(form.year, form.month, form.day)>
<cfoutput>
<ul>
   <li>Formatted with CreateDate: #CreateDate(form.year, form.month, form.day)#
   <li>Formatted with CreateDateTime: #CreateDateTime(form.year, form.month,
form.day, 12,13,0)#
   <li>Formatted with CreateODBCDate: #CreateODBCDate(yourDate)#
   <li>Formatted with CreateODBCDateTime: #CreateODBCDateTime(yourDate)#
</ul>

<p>The same value can be formatted with dateFormat:
<ul>
   <li>Formatted with CreateDate and dateFormat:
         #DateFormat(CreateDate(form.year, form.month, form.day), "mmm-dd-yyyy")#
   <li>Formatted with CreateDateTime and dateFormat:
         #DateFormat(CreateDateTime(form.year, form.month, form.day, 12,13,0))#
   <li>Formatted with CreateODBCDate and dateFormat:
         #DateFormat(CreateODBCDate(yourDate), "mmmm d, yyyy")#
   <li>Formatted with CreateODBCDateTime and dateFormat:
         #DateFormat(CreateODBCDateTime(yourDate), "d/m/yy")#
</ul>
</cfoutput>
</CFIF>
<CFFORM ACTION="createdate.cfm" METHOD="POST">
<p>Enter the year, month and day, as integers:
<PRE>
Year   <CFINPUT TYPE="Text" NAME="year" VALUE="1998" VALIDATE="integer"
      REQUIRED="Yes">
Month   <CFINPUT TYPE="Text" NAME="month" VALUE="6" VALIDATE="integer"
      REQUIRED="Yes">
Day   <CFINPUT TYPE="Text" NAME="day" VALUE="8" VALIDATE="integer"
      REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateDateTime

Description

Creates a date-time object.

Return value

A date/time value.

Category

Date and time functions

Syntax

CreateDateTime(year, month, day, hour, minute, second)

See also

CreateDate , CreateTime , CreateODBCDateTime , Now

Parameters

Parameter | Description
year | Integer, in the range 0-9999. See How ColdFusion processes two-digit year values.
month | Number in the range 1 (January)–12 (December)
day | Number in the range 1–31
hour | Number in the range 0–23
minute | Number in the range 0–59
second | Number in the range 0–59

Example

<h3>CreateDateTime Example</h3>

<CFIF IsDefined("form.year")>
Your date value, generated with CreateDateTime:
<CFSET yourDate = CreateDateTime(form.year, form.month, form.day,
form.hour, form.minute, form.second)>

<cfoutput>
<ul>
   <li>Formatted with CreateDate: #CreateDate(form.year, form.month, form.day)#
   <li>Formatted with CreateDateTime: #CreateDateTime(form.year, form.month,
form.day, form.hour, form.minute, form.second)#
   <li>Formatted with CreateODBCDate: #CreateODBCDate(yourDate)#
   <li>Formatted with CreateODBCDateTime: #CreateODBCDateTime(yourDate)#
</ul>

<p>The same value can be formatted with dateFormat:
<ul>
   <li>Formatted with CreateDate and dateFormat:
      #DateFormat(CreateDate(form.year, form.month, form.day), "mmm-dd-yyyy")#
   <li>Formatted with CreateDateTime and dateFormat:
      #DateFormat(CreateDateTime(form.year, form.month, form.day,
form.hour, form.minute, form.second))#
   <li>Formatted with CreateODBCDate and dateFormat:
      #DateFormat(CreateODBCDate(yourDate), "mmmm d, yyyy")#
   <li>Formatted with CreateODBCDateTime and dateFormat:
      #DateFormat(CreateODBCDateTime(yourDate), "d/m/yy")#
</ul>
</cfoutput>
</CFIF>

<CFFORM ACTION="createdatetime.cfm" METHOD="POST">
<p>Please enter the year, month, and day, in integer format, for a date to view:
<PRE>
Year   <CFINPUT TYPE="Text" NAME="year" VALUE="1998" VALIDATE="integer"
      REQUIRED="Yes">
Month   <CFINPUT TYPE="Text" NAME="month" VALUE="6" RANGE="1,12"
      MESSAGE="Please enter a month (1-12)" VALIDATE="integer"
      REQUIRED="Yes">
Day   <CFINPUT TYPE="Text" NAME="day" VALUE="8" RANGE="1,31"
      MESSAGE="Please enter a day of the month (1-31)" VALIDATE="integer"
      REQUIRED="Yes">
Hour   <CFINPUT TYPE="Text" NAME="hour" VALUE="16" RANGE="0,23"
      MESSAGE="You must enter an hour (0-23)" VALIDATE="integer"
      REQUIRED="Yes">
Minute   <CFINPUT TYPE="Text" NAME="minute" VALUE="12" RANGE="0,59"
      MESSAGE="You must enter a minute value (0-59)" VALIDATE="integer"
      REQUIRED="Yes">
Second   <CFINPUT TYPE="Text" NAME="second" VALUE="0" RANGE="0,59"
      MESSAGE="You must enter a value for seconds (0-59)" VALIDATE="integer"
      REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateObject

Description

Creates a ColdFusion object, of a specified type.

Return value

An object, of the specified type.

Note: You can enable and disable this function in the ColdFusion Administrator, ColdFusion Basic Security, Tag Restrictions page.

Category

Extensibility functions

History

New in ColdFusion MX: This function, and the cfobject tag, can instantiate ColdFusion components and web services. Executing operations on a CFC object executes CFML code that implements the CFC's method in the CFC file.

For more information, see Developing ColdFusion MX Applications with CFML.


CreateObject object types

For information about using this function, see these sections:

  • CreateObject: COM object
  • CreateObject: component object
  • CreateObject: CORBA object
  • CreateObject: Java or EJB object
  • CreateObject: web service object

Note: On UNIX, this function does not support COM objects.


CreateObject: COM object

Description

The CreateObject function can create a Component Object Model (COM) object.

To create a COM object, you must provide this information:

  • The object’s program ID or filename
  • The methods and properties available to the object through the IDispatch interface
  • The arguments and return types of the object's methods

For most objects, you can get this information from the OLEView utility.

Note: On UNIX, this function does not support COM objects.

Return value

A COM object.

Syntax

CreateObject(type, class, context, serverName)

Parameters

Parameter
Description
type
Type of object to create.
  • com
  • corba
  • java
  • component
  • webservice
class
Component ProgID for the object to invoke
context
  • InProc
  • Local
  • Remote
serverName
Server name, using UNC or DNS convention, in one of these forms:
  • \\lanserver
  • lanserver
  • http://www.servername.com
  • www.servername.com
  • 127.0.0.1
If context = "remote", this parameter is required.

Usage

The following example creates the Windows Collaborative Data Objects (CDO) for NTS NewMail object to send mail. You would use this code within a cfscript tag.

Mailer = CreateObject("COM", "CDONTS.NewMail");

For more information, see Developing ColdFusion MX Applications with CFML.


CreateObject: component object

Description

The CreateObject function can create a ColdFusion component (CFC) object.

Return value

A component object.

Syntax

CreateObject(type, component-name)

Parameters

Parameter
Description
type
Type of object to create.
  • com
  • corba
  • java
  • component
  • webservice
component-name
name of a component method

Usage

In the following example, the CFScript statements assign the tellTimeCFC variable to the tellTime component using the createObject function. The createObject function references the component in another directory. To invoke component methods, you use function syntax. For more information, see Developing ColdFusion MX Applications with CFML.

Example

<b>Server's Local Time:</b>
<cfscript>
   tellTimeCFC=createObject("component","appResources.components.
      tellTime");
   tellTimeCFC.getLocalTime();
</cfscript>
<br>
<b>Calculated UTC Time:</b>
<cfscript>
   tellTimeCFC.getUTCTime();
</cfscript>


CreateObject: CORBA object

Description

The CreateObject function can call a method on a CORBA object. The object must be defined and registered for use.

Return value

A handle to a CORBA interface.

Syntax

CreateObject(type, context, class, locale)

History

New in ColdFusion MX: the Naming Service separator format for addresses has changed from a dot to a forward slash. For example, if "context=NameService", for a class, use either of the following formats for the class parameter:

  • "Macromedia/Eng/CF"
  • "Macromedia.current/Eng.current/CF"

(In earlier releases, the format was "Macromedia.Eng.CF".)

New in ColdFusion MX: the locale attribute specifies the Java config that contains the properties file.

Parameters

Parameter
Description
type
Type of object to create.
  • com
  • corba
  • java
  • component
  • webservice
context
  • IOR: ColdFusion uses IOR to access CORBA server
  • NameService: ColdFusion uses naming service to access server. Valid only with the InitialContext of a VisiBroker ORB.
class
  • If context = "ior": absolute path of file that contains string version of the Interoperable Object Reference (IOR). ColdFusion must be able to read file; it should be local to ColdFusion server or accessible on network
  • If context = "nameservice:" forward slash-delimited naming context for naming service. For example: Allaire//Doc/empobject
locale
The name of the Java config that holds the properties file. For more information, see Administering ColdFusion MX.

Usage

In the class attribute, if "context=NameService", use a dot separator for the first part of the string. Use either of the following formats:

  • "Macromedia/Eng/CF"
  • "Macromedia.current/Eng.current/CF"

ColdFusion Enterprise supports CORBA through the Dynamic Invocation Interface (DII). To use this function with CORBA objects, you must provide the name of the file that contains a string version of the IOR, or the object’s naming context in the naming service. You must provide the object’s attributes, method names and method signatures.

This function supports user-defined types (structures, arrays, and sequences).

Example

myobj = CreateObject("corba", "d:\temp\tester.ior", "ior",
"visibroker") //    uses IOR

myobj =    CreateObject("corba", "Macromedia/Eng/CF",
"nameservice", "visibroker")    // uses nameservice

myobj =    CreateObject("corba", "d:\temp\tester.ior",
"nameservice")    // uses nameservice and default configuration


CreateObject: Java or EJB object

Description

The CreateObject function can create a Java object, and, by extension, an EJB object.

Return value

A Java object.

Syntax

CreateObject(type, class)

Parameters

Parameter
Description
type
Type of object to create.
  • com
  • corba
  • java
  • component
  • webservice
class
A Java class name

Usage

Any Java class available in the class path that is specified in the ColdFusion Administrator can be loaded and used from ColdFusion with the CreateObject function.

To access Java methods and fields:

  1. Call the CreateObject function or the cfobject tag to load the class.
  2. Use the init method, with appropriate arguments, to call an instance of the class. For example:
    3. <cfset ret = myObj.init(arg1, arg2)>

Calling a public method on the object without first calling the "init" method invokes a static method. Arguments and return values can be any Java type (simple, array, object). If strings are passed as arguments, ColdFusion does the conversions; if strings are received as return values, ColdFusion does no conversion.

Overloaded methods are supported if the number of arguments is different. Future enhancements will let you use cast functions that allow method signatures to be built more accurately.


CreateObject: web service object

Description

This function can create a web service object.

Return value

A web service object.

Syntax

CreateObject(type, urltowsdl)

Parameters

Parameter
Description
type
Type of object to create.
  • com
  • corba
  • java
  • component
  • webservice
urltowsdl
WSDL file URL; location of web service

Usage

You can use the createObject function to create a web service.

Example

newobject2 = createObject("webservice","wsdlurl")


CreateODBCDate

Description

Creates an ODBC date object.

Return value

A date object, in normalized ODBC date format.

Category

Date and time functions

Syntax

CreateODBCDate(date)

See also

CreateDate , CreateODBCDateTime

Parameters

Parameter | Description
date | Date or date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

This function does not parse or validate values. To ensure that dates are entered and processed correctly (for example, to ensure that a day/month/year entry is not confused with a month/day/year entry, and so on), Macromedia recommends that you parse entered dates with the DateFormat function, using the mm-dd-yyyy mask, into three elements. Ensure that values are within appropriate ranges; for example, to validate a month value, use the attributes validate = "integer" and range = "1,12".

<h3>CreateODBCDate Example</h3>
<CFIF IsDefined("form.year")>
<p>Your date value, generated with CreateDateTime:
<CFSET yourDate = CreateDateTime(form.year, form.month, form.day, form.hour,
form.minute, form.second)>
<cfoutput>
<ul>
   <li>Formatted with CreateDate: #CreateDate(form.year, form.month, form.day)#
   <li>Formatted with CreateDateTime:
      #CreateDateTime(form.year, form.month, form.day, form.hour, form.minute,
form.second)#
   <li>Formatted with CreateODBCDate: #CreateODBCDate(yourDate)#
   <li>Formatted with CreateODBCDateTime: #CreateODBCDateTime(yourDate)#
</ul>
<p>The same value can be formatted with dateFormat:
<ul>
   <li>Formatted with CreateDate and dateFormat:
      #DateFormat(CreateDate(form.year,form.month, form.day), "mmm-dd-yyyy")#
   <li>Formatted with CreateDateTime and dateFormat:
      #DateFormat(CreateDateTime(form.year, form.month, form.day, form.hour,
form.minute, form.second))#
   <li>Formatted with CreateODBCDate and dateFormat:
      #DateFormat(CreateODBCDate(yourDate), "mmmm d, yyyy")#
   <li>Formatted with CreateODBCDateTime and dateFormat:
      #DateFormat(CreateODBCDateTime(yourDate), "d/m/yy")#
</ul>
</cfoutput>
</CFIF>
<CFFORM ACTION="createodbcdate.cfm" METHOD="POST">
<p>Enter the year, month and day, as integers:
<PRE>
Year      <CFINPUT TYPE="Text" NAME="year" VALUE="1998" VALIDATE="integer"
      REQUIRED="Yes">
Month      <CFINPUT TYPE="Text" NAME="month" VALUE="6" RANGE="1,12"
      MESSAGE="Please enter a month (1-12)" VALIDATE="integer"
      REQUIRED="Yes">
Day          <CFINPUT TYPE="Text" NAME="day" VALUE="8" RANGE="1,31"
      MESSAGE="Please enter a day of the month (1-31)" VALIDATE="integer"
      REQUIRED="Yes">
Hour      <CFINPUT TYPE="Text" NAME="hour" VALUE="16" RANGE="0,23"
      MESSAGE="You must enter an hour (0-23)" VALIDATE="integer"
      REQUIRED="Yes">
Minute      <CFINPUT TYPE="Text" NAME="minute" VALUE="12" RANGE="0,59"
      MESSAGE="You must enter a minute value (0-59)" VALIDATE="integer"
      REQUIRED="Yes">
Second      <CFINPUT TYPE="Text" NAME="second" VALUE="0" RANGE="0,59"
      MESSAGE="You must enter a value for seconds (0-59)" VALIDATE="integer"
      REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateODBCDateTime

Description

Creates an ODBC date-time object.

Return value

A date/time object, in ODBC timestamp format.

Category

Date and time functions

Syntax

CreateODBCDateTime(date)

See also

CreateDateTime , CreateODBCDate , CreateODBCTime , Now

Parameters

Parameter | Description
date | Date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<!--- This example shows how to use Createdate, Createdatetime, createODBCdate
and createODBCDateTime --->
<h3>CreateODBCDateTime Example</h3>

<CFIF IsDefined("form.year")>
Your date value, generated using CreateDateTime:
<CFSET yourDate = CreateDateTime (form.year, form.month, form.day,
form.hour,form.minute, form.second)>
<cfoutput>
<ul>
   <li>Formatted with CreateDate: #CreateDate(form.year, form.month,form.day)#
   <li>Formatted with CreateDateTime: #CreateDateTime(form.year,form.month,
      form.day,form.hour,form.minute,form.second)#
   <li>Formatted with CreateODBCDate: #CreateODBCDate(yourDate)#
   <li>Formatted with CreateODBCDateTime: #CreateODBCDateTime(yourDate)#
</ul>
<p>The same value can be formatted with dateFormat:
<ul>
   <li>Formatted with CreateDate and DateFormat:
      #DateFormat(CreateDate(form.year,form.month,form.day), "mmm-dd-yyyy")#
   <li>Formatted with CreateDateTime and DateFormat:
      #DateFormat(CreateDateTime(form.year,form.month,form.day,
      form.hour,form.minute,form.second))#
   <li>Formatted with CreateODBCDate and DateFormat:
      #DateFormat(CreateODBCDate(yourDate), "mmmm d, yyyy")#
   <li>Formatted with CreateODBCDateTime and DateFormat:
      #DateFormat(CreateODBCDateTime(yourDate), "d/m/yy")#
</ul>
</cfoutput>
</CFIF>
<CFFORM ACTION="createodbcdatetime.cfm" METHOD="POST">
<p>Enter a year, month and day, as integers:
<PRE>
Year      <CFINPUT
         TYPE="Text"  NAME="year" VALUE="1998" VALIDATE="integer" REQUIRED="Yes">

Month      <CFINPUT
         TYPE="Text" NAME="month"  VALUE="6"  RANGE="1,12"
         MESSAGE="Enter a month (1-12)" VALIDATE="integer" REQUIRED="Yes">

Day      <CFINPUT TYPE="Text" NAME="day" VALUE="8" RANGE="1,31"
         MESSAGE="Enter a day of the month (1-31)" VALIDATE="integer"
REQUIRED="Yes">

Hour      <CFINPUT TYPE="Text" NAME="hour" VALUE="16" RANGE="0,23"
         MESSAGE="You must enter an hour (0-23)" VALIDATE="integer" REQUIRED="Yes">

Minute      <CFINPUT TYPE="Text" NAME="minute" VALUE="12" RANGE="0,59"
         MESSAGE="You must enter a minute value (0-59)" VALIDATE="integer"
REQUIRED="Yes">

Second      <CFINPUT TYPE="Text" NAME="second" VALUE="0" RANGE="0,59"
         MESSAGE="You must enter a seconds value (0-59)" VALIDATE="integer"
REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateODBCTime

Description

Creates an ODBC time object.

Return value

A time object, in ODBC timestamp format.

Category

Date and time functions

Syntax

CreateODBCTime(date)

See also

CreateODBCDateTime , CreateTime

Parameters

Parameter | Description
date | Date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<h3>CreateODBCTime Example</h3>
<CFIF IsDefined("form.hour")>
Your time value, created with CreateTime...
<CFSET yourTime = CreateTime(form.hour, form.minute, form.second)>
<cfoutput>
<ul>
   <li>Formatted with CreateODBCTime: #CreateODBCTime(yourTime)#
   <li>Formatted with TimeFormat: #TimeFormat(yourTime)#
</ul></cfoutput>
</CFIF>
<CFFORM action="createodbctime.cfm" METHOD="post">
<PRE>
Hour      <CFINPUT TYPE="Text" NAME="hour" VALUE="16" RANGE="0,23" MESSAGE="You must
enter an hour (0-23)" VALIDATE="integer" REQUIRED="Yes">
Minute      <CFINPUT TYPE="Text" NAME="minute" VALUE="12" RANGE="0,59" MESSAGE="You must
enter a minute value (0-59)" VALIDATE="integer" REQUIRED="Yes">
Second      <CFINPUT TYPE="Text" NAME="second" VALUE="0" RANGE="0,59" MESSAGE="You must
enter a value for seconds (0-59)" VALIDATE="integer" REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateTime

Description

Creates a time variable.

Return value

A time variable.

Category

Date and time functions

Syntax

CreateTime(hour, minute, second)

See also

CreateODBCTime , CreateDateTime

Parameters

Parameter | Description
hour | Number in the range 0–23
minute | Number in the range 0–59
second | Number in the range 0–59

Usage

CreateTime is a subset of CreateDateTime.

A time variable is a special case of a date/time variable. The date part of a time variable is set to December 30, 1899.

Example

<h3>CreateTime Example</h3>
<cfif IsDefined("FORM.hour")>
Your time value, presented using CreateTime time function:
<cfset yourTime = CreateTime(FORM.hour, FORM.minute, FORM.second)>
<cfoutput><ul>
   <li>Formatted with timeFormat: #TimeFormat(yourTime)#
   <li>Formatted with timeFormat and hh:mm:ss: #TimeFormat(yourTime, 'hh:mm:ss')#
</ul></cfoutput>
</cfif>
<CFFORM action="createtime.cfm" METHOD="post">
<PRE>Hour         <CFINPUT TYPE="Text" NAME="hour" VALUE="16" RANGE="0,23"
   MESSAGE="You must enter an hour (0-23)" VALIDATE="integer" REQUIRED="Yes">
Minute         <CFINPUT TYPE="Text" NAME="minute" VALUE="12" RANGE="0,59"
   MESSAGE="You must enter a minute value (0-59)" VALIDATE="integer"
REQUIRED="Yes">
Second         <CFINPUT TYPE="Text" NAME="second" VALUE="0" RANGE="0,59"
   MESSAGE="You must enter a value for seconds (0-59)" VALIDATE="integer"
REQUIRED="Yes">
</PRE>
<p><INPUT TYPE="Submit" NAME=""> <INPUT TYPE="RESET">
</cfform>


CreateTimeSpan

Description

Creates a date/time object that defines a time period. You can add or subtract it from other date/time objects and use it with the cachedWithin attribute of cfquery.

Return value

A date/time object.

Category

Date and time functions

Syntax

CreateTimeSpan(days, hours, minutes, seconds)

See also

CreateDateTime , DateAdd , DateConvert

Parameters

Parameter | Description
days | Integer in the range 0–32768; number of days in time period
hours | Number of hours in time period
minutes | Number of minutes in time period
seconds | Number of seconds in time period

Usage

Creates a special date/time object that should be used only to add and subtract from other date/time objects or with the cfquery cachedWithin attribute.

If you use the cachedWithin attribute of cfquery, and the original query date falls within the time span you define, cached query data is used. In this case, the CreateTimeSpan function is used to define a period of time from the present backwards. The cachedWithin attribute takes effect only if you enable query caching in the ColdFusion Administrator. For more information, see cfquery.

Example

<!--- This example shows the use of CreateTimeSpan with cfquery --->
<h3>CreateTimeSpan Example</h3>
<!--- define startrow and maxrows to facilitate 'next N' style browsing --->
<CFPARAM name = "MaxRows" default = "10">
<CFPARAM name = "StartRow" default = "1">
<!--- Query database for information, if cached database information has not been
updated in the last six hours. -------->
<cfoutput>
<cfquery name = "GetParks" datasource = "cfsnippets"
   cachedWithin = "#CreateTimeSpan(0, 6, 0, 0)#">
SELECT   PARKNAME, REGION, STATE
FROM     Parks
ORDER by ParkName, State
</cfquery>
</cfoutput>
<!--- build HTML table to display query --->
<TABLE cellpadding = 1 cellspacing = 1>
<TR>
   <TD colspan = 2 bgcolor = f0f0f0>
   <B><I>Park Name</I></B>
   </TD>
   <TD bgcolor = f0f0f0>
   <B><i>Region</I></B>
   </TD>
   <TD bgcolor = f0f0f0>
   <B><I>State</I></B>
   </TD>
</TR>
<!--- Output query, define startrow and maxrows. Use query variable CurrentCount to
track the row you are displaying. --->
<cfoutput query = "GetParks" StartRow = "#StartRow#"
MAXROWS = "#MaxRows#">
<TR>
   <TD valign = top bgcolor = ffffed>
   <B>#GetParks.CurrentRow#</B>
   </TD>
   <TD valign = top>
   <FONT SIZE = "-1">#ParkName#</FONT>
   </TD>
   <TD valign = top>
   <FONT SIZE = "-1">#Region#</FONT>
   </TD>
   <TD valign = top>
   <FONT SIZE = "-1">#State#</FONT>
   </TD>
</TR>
</cfoutput>
<!--- If number of records is less than or equal to number of rows, offer link to
same page, with startrow value incremented by maxrows (in this example,
incremented by 10) --->
<TR>
   <TD colspan = 4>
   <cfif (StartRow + MaxRows) LTE GetParks.RecordCount>
      <a href = "cfquery.cfm?startrow = <cfoutput>
      #Evaluate(StartRow + MaxRows)#</cfoutput>">
      See next <cfoutput>#MaxRows#</cfoutput> rows</A>
   </cfif>
   </TD>
</TR>
</TABLE>


CreateUUID

Description

Creates a Universally Unique Identifier (UUID). A UUID is a 35-character string representation of a unique 128-bit integer.

The ColdFusion UUID generation algorithm uses the unique time-of-day value, the IEEE 802 Host ID, and a cryptographically strong random number generator to generate UUIDs that conform to the principles laid out in the draft IEEE RFC "UUIDs and GUIDs."

The ColdFusion UUID format is as follows:

xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx (8-4-4-16).

This does not conform to the Microsoft/DCE standard, which is as follows:

xxxxxxxx-xxxx-xxxx-xxxxxx-xxxxxxxxxx (8-4-4-6-10)

There are UUID test tools and a user-defined function called CreateGUID, which converts CFML UUIDs to UUID/Microsoft GUID format, available on the web at www.cflib.org.

Return value

A UUID, in the format xxxxxxxx-xxxx-xxxx-xxxxxxxxxxxxxxxx, where x is a hexadecimal digit (0-9 or A-F). (The character groups are 8-4-4-16.)

Category

Other functions

Syntax

CreateUUID()

Usage

Use this function to generate a persistent identifier in a distributed environment. To a very high degree of certainty, this function returns a unique value; no other invocation on the same or any other system returns the same value.

UUIDs are used by distributed computing frameworks, such as DCE/RPC, COM+, and CORBA. In ColdFusion, you can use UUIDs as primary table keys for applications in which data is stored in shared databases. In such cases, using numeric keys can cause primary-key constraint violations during table merges. Using UUIDs, you can eliminate these violations.

Example

<h3>CreateUUID Example</h3>
<p> This example uses CreateUUID to generate a UUID when you submit the form.
You can submit the form more than once. </p>
<!--- Checks whether the form was submitted; if so, creates UUID. --->
<cfif IsDefined("Form.CreateUUID") Is True>
   <hr>
   <p>Your new UUID is: <cfoutput>#CreateUUID()#</cfoutput></p>
</cfif>
<form action = "createuuid.cfm">
<p><input type = "Submit" name = "CreateUUID"> </p>
</form>


DateAdd

Description

Adds units of time to a date.

Return value

A date/time object.

Category

Date and time functions

Syntax

DateAdd("datepart", number, "date")

See also

DateConvert , DatePart , CreateTimeSpan

Parameters

Parameter
Description
datepart
String:
  • yyyy: Year
  • q: Quarter
  • m: Month
  • y: Day of year
  • d: Day
  • w: Weekday
  • ww: Week
  • h: Hour
  • n: Minute
  • s: Second
number
Number of units of datepart to add to date (positive, to get dates in the future; negative, to get dates in the past)
date
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

The datepart specifiers y, d, and w add a number of days to a date.

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Example

<!--- This example shows the use of DateAdd --->
...
<cfquery name = "GetMessages" datasource = "cfsnippets">
SELECT UserName, Subject, Posted
FROM Messages
</cfquery>
<p>This example uses DateAdd to determine when a message in the database
expires. (The value selected is messages older than <cfoutput>#value#
<cfswitch expression = #type#>
   <cfcase value = "yyyy">years</cfcase>
   <cfcase value = "q">quarters</cfcase>
   <cfcase value = "m">months</cfcase>
   <cfcase value = "y">days of year</cfcase>
   <cfcase value = "w">weekdays</cfcase>
   <cfcase value = "ww">weeks</cfcase>
   <cfcase value = "h">hours</cfcase>
   <cfcase value = "n">minutes</cfcase>
   <cfcase value = "s">seconds</cfcase>
   <CFDEFAULTCASE>years</CFDEFAULTCASE>
</cfswitch>
</cfoutput>).

<TABLE>
<TR>
   <TD>UserName</TD>
   <TD>Subject</TD>
   <TD>Posted</TD>
</TR>
<cfoutput query = "GetMessages">
<TR>
   <TD>#UserName#</td>
   <d>#Subject#</d>
   <d>#Posted# <cfif DateAdd(type, value, posted)
LT Now()>EXPIRED</cfif></d>
</tr>
</cfoutput>
</table>


DateCompare

Description

Performs a full date/time comparison of two dates.

Return value

  • -1, if date1 is less than date2
  • 0, if date1 is equal to date2
  • 1, if date1 is greater than date2

Category

Date and time functions

Syntax

DateCompare("date1", "date2" [, "datePart"])

See also

CreateDateTime , DatePart

Parameters

Parameter
Description
date1
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
date2
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
datePart
Optional. String. Precision of the comparison.
  • s Precise to the second (default)
  • n Precise to the minute
  • h Precise to the hour
  • d Precise to the day
  • m Precise to the month
  • yyyy Precise to the year

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Example

<h3>DateCompare Example</h3>
<p>The datecompare function compares two date/time values.
<cfif IsDefined("FORM.date1")>
   <cfif IsDate(FORM.date1) and IsDate(FORM.date2)>
      <cfset comparison = DateCompare(FORM.date1, FORM.date2, FORM.precision)>

<!--- switch on the variable to give various responses --->
      <cfswitch expression = #comparison#>
         <cfcase value = "-1">
            <h3><cfoutput>#DateFormat(FORM.date1)#
            #TimeFormat(FORM.date1)#</cfoutput> (Date 1) is
            earlier than <cfoutput>#DateFormat(FORM.date2)#
            #TimeFormat(FORM.date2)#</cfoutput> (Date 2)</h3>
            <I>The dates are not equal</I>
         </cfcase>
         <cfcase value = "0">
            <h3><cfoutput>#DateFormat(FORM.date1)#
            #TimeFormat(FORM.date1)#</cfoutput> (Date 1) is equal
            to <cfoutput>#DateFormat(FORM.date2)#
            #TimeFormat(FORM.date2)#</cfoutput> (Date 2)</h3>
            <I>The dates are equal!</I>
         </cfcase>
         <cfcase value = "1">
            <h3><cfoutput>#DateFormat(FORM.date1)#
            #TimeFormat(FORM.date1)#</cfoutput> (Date 1) is later
            than <cfoutput>#DateFormat(FORM.date2)#
            #TimeFormat(FORM.date2)#</cfoutput> (Date 2)</h3>
            <I>The dates are not equal</I>
         </cfcase>
         <CFDEFAULTCASE>
            <h3>This is the default case</h3>
         </CFDEFAULTCASE>
      </cfswitch>
   <cfelse>
      <h3>Enter two valid date values</h3>
   </cfif>
</cfif>

<form action = "datecompare.cfm">
<hr size = "2" color = "#0000A0">
<p>Date 1
<br><input type = "Text" name = "date1"
      value = "<cfoutput>#DateFormat(Now())# #TimeFormat(Now())#
</cfoutput>">
<p>Date 2
<br><input type = "Text" name = "date2"
      value = "<cfoutput>#DateFormat(Now())# #TimeFormat(Now())#
</cfoutput>">
<p>Specify precision to the:
<br><select name = "precision">
         <option value = "s">
            Second
         </option>
         <option value = "n">
            Minute
         </option>
         <option value = "h">
            Hour
         </option>
         <option value = "d">
            Day
         </option>
         <option value = "m">
            Month
         </option>
         <option value = "yyyy">
            Year
         </option>
   </select>
<p><input type = "Submit" value = "Compare these dates" name = "">
<input type = "reset">
</form>


DateConvert

Description

Converts local time to Coordinated Universal Time (UTC), or UTC to local time. The function uses the daylight savings settings in the executing computer to compute daylight savings time, if required.

Return value

UTC- or local-formatted time object.

Category

Date and time functions

Syntax

DateConvert("conversion-type", "date")

See also

GetTimeZoneInfo , CreateDateTime , DatePart

Parameters

Parameter
Description
conversion-type
  • local2Utc: Converts local time to UTC time.
  • utc2Local: Converts UTC time to local time.
date
Date and time string or a variable that contains one.
To create, use CreateDateTime.

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate or Now function as the date parameter of this function; for example: #DateConvert(CreateDate(2001, 3, 3))#

Example

<h3>DateConvert Example</h3>
<!--- This shows conversion of current date - time to UTC and back. --->
<cfset curDate = Now()>
<p><cfoutput>The current date and time: #curDate#. </cfoutput></p>
<cfset utcDate = DateConvert("local2utc", curDate)>
<cfoutput>
   <p>The current date and time converted to UTC time: #utcDate#.</p>
</cfoutput>
<!--- This code checks whether form was submitted. If so, the code generates
the CFML date with the CreateDateTime function. --->
<cfif IsDefined("FORM.submit")>
   <cfset yourDate = CreateDateTime(FORM.year, FORM.month, FORM.day,
FORM.hour,FORM.minute, FORM.second)>
   <p><cfoutput>Your date value, presented as a ColdFusion date/time
string:#yourdate#.</cfoutput></p>
  <cfset yourUTC = DateConvert("local2utc", yourDate)>
   <p><cfoutput>Your date and time value, converted to Coordinated Universal Time
(UTC): #yourUTC#.</cfoutput></p>
   <p><cfoutput>Your UTC date and time, converted back to local date and time:
#DateConvert("utc2local", yourUTC)#.
</cfoutput></p>
<cfelse>
   Type the date and time, and press Enter to see the conversion.
</cfif>
<Hr size = "2" color = "#0000A0">
<form action = "dateconvert.cfm">
<p>Enter year, month and day in integer format for date value to view:
<table cellspacing = "2" cellpadding = "2" border = "0">
<tr>
  <td>Year</td>
  <td><input type = "Text" name = "year" value = "1998"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td>Month</td>
  <td><input type = "Text" name = "month" value = "6"
range = "1,12" message = "Enter a month (1-12)"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td>Day</td>
  <td><input type = "Text" name = "day" value = "8"
range = "1,31"
message = "Enter a day of the month (1-31)"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td>Hour</td>
  <td><input type = "Text" name = "hour" value = "16"
range = "0,23"
message = "You must enter an hour (0-23)"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td>Minute</td>
  <td><input type = "Text" name = "minute" value = "12"
range = "0,59"
message = "You must enter a minute value (0-59)"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td>Second</td>
  <td><input type = "Text" name = "second" value = "0"
range = "0,59"
message = "You must enter a value for seconds (0-59)"
validate = "integer" required = "Yes"></td></tr>
<tr>
  <td><input type = "Submit" name = "submit" value = "Submit"></td>
  <td><input type = "RESET"></td></tr>
</table>


DateDiff

Description

Determines the number of units by which date1 is less than date2.

Return value

A number of units, of type datepart.

Category

Date and time functions

Syntax

DateDiff("datepart", "date1", "date2")

See also

DateAdd , DatePart , CreateTimeSpan

History

New in ColdFusion MX: This function now calculates negative date differences correctly; its output may be different from that in earlier releases.

Parameters

Parameter
Description
datepart
String:
  • yyyy: Year
  • q: Quarter
  • m: Month
  • y: Day of year
  • d: Day
  • w: Weekday
  • ww: Week
  • h: Hour
  • n: Minute
  • s: Second
date1
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
date2
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

To find the number of days between date1 and date2, use DayofYear or Day.

When datepart is Weekday, DateDiff returns the number of weeks between the dates. If date1 falls on a Monday, DateDiff counts the number of Mondays to date2. It counts date2 but not date1.

If interval is Week, however, DateDiff returns the number of calendar weeks between the dates. It counts the number of Sundays between date1 and date2. DateDiff counts date2 if it falls on a Sunday; it does not count date1, even if it falls on a Sunday.

If date1 refers to a later date than date2, DateDiff returns a negative number.

When passing date/time object as a string, enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Example

<!--- This example shows the use of DateDiff --->
<cfif IsDefined("FORM.date1") and IsDefined("FORM.date2")>
   <cfif IsDate(FORM.date1) and IsDate(FORM.date2)>
      <p>This example uses DateDiff to determine the difference
      in    <cfswitch expression = #type#>
         <cfcase value = "yyyy">years</cfcase>
         <cfcase value = "q">quarters</cfcase>
         <cfcase value = "m">months</cfcase>
         <cfcase value = "y">days of year</cfcase>
         <cfcase value = "d">days</cfcase>
         <cfcase value = "w">weekdays</cfcase>
         <cfcase value = "ww">weeks</cfcase>
         <cfcase value = "h">hours</cfcase>
         <cfcase value = "n">minutes</cfcase>
         <cfcase value = "s">seconds</cfcase>
         <CFDEFAULTCASE>years</CFDEFAULTCASE></cfswitch>
          dateparts between date1 and date2.
      <cfif DateCompare(FORM.date1, FORM.date2) is not 0>
      <p>The difference is <cfoutput>#Abs(DateDiff
       (type, FORM.date2, FORM.date1))#</cfoutput>
      <cfswitch expression = #type#>
         <cfcase value = "yyyy">years</cfcase>
         <cfcase value = "q">quarters</cfcase>
         <cfcase value = "m">months</cfcase>
         <cfcase value = "y">days of year</cfcase>
         <cfcase value = "d">days</cfcase>
         <cfcase value = "w">weekdays</cfcase>
         <cfcase value = "ww">weeks</cfcase>
         <cfcase value = "h">hours</cfcase>
         <cfcase value = "n">minutes</cfcase>
         <cfcase value = "s">seconds</cfcase>
         <CFDEFAULTCASE>years</CFDEFAULTCASE></cfswitch>.
      <cfelse>
...


DateFormat

Description

Formats a date value. Supports dates in the U.S. date format. For international date support, use LSDateFormat.

Return value

A formatted date/time object. If no mask is specified, returns the value in dd-mmm-yy format.

Category

Date and time functions

Syntax

DateFormat("date" [, "mask" ])

See also

Now , CreateDate , LSDateFormat, LSParseDateTime , LSTimeFormat , TimeFormat , ParseDateTime

History

New in ColdFusion MX: This function supports the short, medium, long, and full mask attribute options.

Parameters

Parameter
Description
date
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
mask
Characters that show how ColdFusion displays a date:
  • d: Day of the month as digits; no leading zero for single-digit days.
  • dd: Day of the month as digits; leading zero for single-digit days.
  • ddd: Day of the week as a three-letter abbreviation.
  • dddd: Day of the week as its full name.
  • m: Month as digits; no leading zero for single-digit months.
  • mm: Month as digits; leading zero for single-digit months.
  • mmm: Month as a three-letter abbreviation.
  • mmmm: Month as its full name.
  • y: Year as last two digits; no leading zero for years less than 10.
  • yy: Year as last two digits; leading zero for years less than 10.
  • yyyy: Year represented by four digits.
  • gg: Period/era string. Ignored. Reserved.
  • short
  • medium
  • long
  • full

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate function or Now function as the date parameter of this function; for example: #DateFormat(CreateDate(2001, 3, 3))#

If the switch is set, the default date format returned by this function cannot be parsed in an expression. However, if you specify a mask to indicate order (such as mm/dd/yyyy), the date returned by this function can be parsed.

Date and time values in database query results can vary in sequence and formatting unless you use functions to format them. To ensure that application users correctly understand displayed dates and times, Macromedia recommends that you use this function and the LSDateFormat, TimeFormat, and LSTimeFormat functions to format resultset values. For more information and examples, see TechNote 22183, "ColdFusion Server (5 and 4.5.x) with Oracle: Formatting Date and Time Query Results," on our Web site at .

Example

<cfset todayDate = Now()>
<body>
<h3>DateFormat Example</h3>
<p>Today’s date is <cfoutput>#todayDate#</cfoutput>.
<p>Using DateFormat, we can display that date in different ways:
<cfoutput>
<ul>
   <li>#DateFormat(todayDate)#
   <li>#DateFormat(todayDate, "mmm-dd-yyyy")#
   <li>#DateFormat(todayDate, "mmmm d, yyyy")#
   <li>#DateFormat(todayDate, "mm/dd/yyyy")#
   <li>#DateFormat(todayDate, "d-mmm-yyyy")#
   <li>#DateFormat(todayDate, "ddd, mmmm dd, yyyy")#
   <li>#DateFormat(todayDate, "d/m/yy")#
</ul>
</cfoutput>


DatePart

Description

Extracts a part from a date value.

Return value

Part of a date, as an integer.

Category

Date and time functions

Syntax

DatePart("datepart", "date")

See also

DateAdd, DateConvert

Parameters

Parameter
Description
datepart
String:
  • yyyy: Year
  • q: Quarter
  • m: Month
  • y: Day of year
  • d: Day
  • w: Weekday
  • ww: Week
  • h: Hour
  • n: Minute
  • s: Second
date
Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Example

<!--- This example shows information available from DatePart --->
<cfset todayDate = Now()>
<h3>DatePart Example</h3>
<p>Today’s date is <cfoutput>#todayDate#</cfoutput>.
<p>Using datepart, we extract an integer representing the dateparts from that value
<cfoutput>
<ul>
   <li>year: #DatePart("yyyy", todayDate)#
   <li>quarter: #DatePart("q", todayDate)#
   <li>month: #DatePart("m", todayDate)#
   <li>day of year: #DatePart("y", todayDate)#
   <li>day: #DatePart("d", todayDate)#
   <li>weekday: #DatePart("w", todayDate)#
   <li>week: #DatePart("ww", todayDate)#
   <li>hour: #DatePart("h", todayDate)#
   <li>minute: #DatePart("n", todayDate)#
   <li>second: #DatePart("s", todayDate)#
</ul>
</cfoutput>


Day

Description

Determines the day of the month, in a date.

Return value

The ordinal for the day of the month, ranging from 1 to 31.

Category

Date and time functions

Syntax

Day("date")

See also

DayOfWeek , DayOfWeekAsString , DayOfYear , DaysInMonth , DaysInYear , FirstDayOfMonth

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate function or Now function as the date parameter of this function; for example: #Day(CreateDate(2001, 3, 3))#

Example

<h3>Day Example</h3>
<cfif IsDefined("FORM.year")>
   <p>More information about your date:
   <cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
   <cfoutput>
      <p>Date: #DateFormat(yourDate)#. <br>
It is #DayofWeekAsString(DayOfWeek(yourDate))#,
day #DayOfWeek(yourDate)# in the week.
      <br>This is day #Day(YourDate)#
in the month of #MonthAsString(Month(yourDate))#,
which has #DaysInMonth(yourDate)# days.
      <br>We are in week #Week(yourDate)# of #Year(YourDate)#
       (day #DayofYear(yourDate)# of #DaysinYear(yourDate)#).
      <br><cfif IsLeapYear(Year(yourDate))>This is a leap year
            <cfelse>This is not a leap year</cfif>
   </cfoutput>
</cfif>


DayOfWeek

Description

Determines the day of the week, in a date.

Return value

The ordinal for the day of the week, as an integer in the range 1 (Sunday) to 7 (Saturday).

Category

Date and time functions

Syntax

DayOfWeek("date")

See also

Day , DayOfWeekAsString , DayOfYear , DaysInMonth , DaysInYear , FirstDayOfMonth

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate function or Now function as the date parameter of this function; for example, #DayOfWeek(CreateDate(2001, 3, 3))#

Example

<h3>DayOfWeek Example</h3>
<cfif IsDefined("FORM.year")>
   More information about your date:
   <cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
   <cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
    #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(YourDate)# in the month of
    #MonthAsString(Month(yourDate))#, which has
    #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(YourDate)# (day
    #DayofYear(yourDate)# of #DaysinYear(yourDate)#).
   <br><cfif IsLeapYear(Year(yourDate))>This is a leap year
      <cfelse>This is not a leap year</cfif>
   </cfoutput>
</cfif>


DayOfWeekAsString

Description

Determines the day of the week, in a date, as a string function.

Return value

The day of the week, as a string that corresponds to day_of_week.

Category

Date and time functions, String functions

Syntax

DayOfWeekAsString(day_of_week)

See also

Day , DayOfWeek , DayOfYear , DaysInMonth , DaysInYear , FirstDayOfMonth

Parameters

Parameter | Description
day_of_week | Integer, in the range 1 (Sunday) - 7 (Saturday).

Example

<h3>DayOfWeekAsString Example</h3>
<cfif IsDefined("FORM.year")>
More information about your date:
<cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>

<cfoutput>
<p>Your date, #DateFormat(yourDate)#.
<br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
    #DayOfWeek(yourDate)# in the week.
<br>This is day #Day(YourDate)# in the month of
#MonthAsString(Month(yourDate))#, which has
     #DaysInMonth(yourDate)# days.
<br>We are in week #Week(yourDate)# of #Year(YourDate)# (day #DayofYear(yourDate)#
of #DaysinYear(yourDate)#).
<br><cfif IsLeapYear(Year(yourDate))>This is a leap year
   <cfelse>This is not a leap year</cfif>
</cfoutput>
</cfif>


DayOfYear

Description

Determines the day of the year, in a date.

Return value

The ordinal value of day of the year, as an integer.

Category

Date and time functions

Syntax

DayOfYear("date")

See also

Day , DayOfWeek , DayOfWeekAsString , DaysInMonth , DaysInYear , FirstDayOfMonth

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

This function accounts for leap years.

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate function or Now function as the date parameter of this function; for example, #DayOfYear(CreateDate(2001, 3, 3))#

Example

<h3>Day7OfYear Example</h3>
<cfif IsDefined("FORM.year")>
   More information about your date:
   <cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
   <cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#,
    day #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(yourDate)# in the month of
    #MonthAsString(Month(yourDate))#, which has
    #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(yourDate)#
(day #DayofYear(yourDate)# of #DaysinYear(yourDate)#).
   <br><cfif IsLeapYear(Year(yourDate))>This is a leap year
      <cfelse>This is not a leap year</cfif>
   </cfoutput>
</cfif>


DaysInMonth

Description

Determines the number of days in a month.

Return value

The number of days in the month in Date.

Category

Date and time functions

Syntax

DaysInMonth("date")

See also

Day , DayOfWeek , DayOfWeekAsString , DayOfYear , DaysInYear , FirstDayOfMonth

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the Now function or the CreateDate function as the date parameter of this function; for example: #DaysInMonth(CreateDate(2001, 3, 3))#

Example

<h3>DaysInMonth Example</h3>
<cfif IsDefined("FORM.year")>
   More information about your date:
   <cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
   <cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
    #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(YourDate)# in the month of
    #MonthAsString(Month(yourDate))#, which has
    #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(YourDate)#
    (day #DayofYear(yourDate)# of #DaysinYear(yourDate)#).
   <br><cfif IsLeapYear(Year(yourDate))>This is a leap year
      <cfelse>This is not a leap year</cfif>
   </cfoutput>
</cfif>


DaysInYear

Description

Determines the number of days in a year.

Return value

The number of days in a year.

Category

Date and time functions

Syntax

DaysInYear("date")

See also

Day , DayOfWeek , DayOfWeekAsString , DayOfYear , DaysInMonth , DaysInYear , FirstDayOfMonth , IsLeapYear

Parameters

Parameter
Description
date
  • Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

DaysInYear accounts for leap years.

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a numeric representation of a date/time object.

Note: You can pass the CreateDate function or the Now function as the date parameter of this function; for example: #DaysInYear(CreateDate(2001, 3, 3))#

Example

<h3>DaysInYear Example</h3>
<cfif IsDefined("FORM.year")>
   More information about your date:
   <cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
   <cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
    #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(YourDate)# in the month of
    #MonthAsString(Month(yourDate))#, which has
    #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(yourDate)# (day
    #DayofYear(yourDate)# of #DaysinYear(yourDate)#).
</cfif>


DE

Description

Postpones evaluation of a string as an expression, when it is passed as a parameter to the IIf or Evaluate functions. Escapes any double quotation marks in the parameter and wraps the result in double quotation marks.

This function is especially useful with the IIf function, to prevent the function from evaluating a string that is to be output.

This applies to expressions that are not surrounded by pound signs. (If pound signs surround any part of an expression, a ColdFusion function evaluates that part first, regardless of whether the DE function is present.)

Return value

Parameter, surrounded by double quotation marks, with any inner double quotation marks escaped.

Category

Dynamic evaluation functions

Syntax

DE(string)

See also

Evaluate , IIf

Parameters

Parameter | Description
string | String to evaluate, after delay

Usage

Consider this example:

<condition> <true expression> <false expression>
iif( 1 eq 2, DE('#Var1#'), DE('#Var2#'))

ColdFusion evaluates whatever is surrounded by pounds in the expression before executing it. So, although this expression is never true (because Var1 does not exist), the expression fails with an 'Error Resolving Parameter' error, because ColdFusion evaluates #Var1#' and #Var2#' before executing either expression.

This example returns 'Var2':

iif( 1 eq 2, DE('Var1'), DE('Var2'))

The following example uses IIF to alternate table-row background colors, white and gray. It uses the DE function to prevent ColdFusion from evaluating the color strings.

<cfoutput>
<table border="1" cellpadding="3">
<cfloop index="i" from="1" to="10">
   <tr bgcolor="#IIF( i mod 2 eq 0, DE("white"), DE("gray") )#">
      <td>
         hello #i#
      </td>
   </tr>
</cfloop>
</table>
</cfoutput>

For more information and code examples, see Developing ColdFusion MX Applications with CFML.

Example

<!--- This example shows the use of DE and Evaluate --->
<h3>DE Example</h3>
<cfif IsDefined("FORM.myExpression")>
<h3>The Expression Result</h3>
<cftry>
<!--- Evaluate the expression --->
<cfset myExpression = Evaluate(FORM.myExpression)>
<!--- Use DE to output the value of the variable, unevaluated --->
<cfoutput>
<I>The value of the expression #Evaluate(DE(FORM.MyExpression))#
is #MyExpression#.</I>
</cfoutput>
<!--- specify the type of error for which we are searching --->
<cfcatch type = "Any">
<!--- the message to display --->
   <h3>Sorry, there’s been an <B>Error</B>.
   Try a simple expression, such as "2+2".</h3>
<cfoutput>
<!--- and the diagnostic message from ColdFusion Server --->
  <p>#cfcatch.message#
</cfoutput>
</cfcatch>
</cftry>
</cfif>


DecimalFormat

Description

Converts a number to a decimal-formatted string.

Return value

A number as a string formatted with two decimal places and a thousands separator.

Category

Display and formatting functions

Syntax

DecimalFormat(number)

See also

DollarFormat , NumberFormat

Parameters

Parameter | Description
number | Number to format

Example

<h3>DecimalFormat Function</h3>
<p>Returns a number to two decimal places.
<p>
<cfloop FROM = 1 TO = 20 INDEX = "counter">
   <cfoutput>
   #counter# * Square Root of 2:
      #DecimalFormat(Evaluate(counter * sqr(2)))#
   </cfoutput>
   <br>
</cfloop>


DecrementValue

Description

Decrements the integer part of a number.

Return value

Integer part of number, decremented by one.

Category

Mathematical functions

Syntax

DecrementValue(number)

See also

IncrementValue

Parameters

Parameter | Description
number | Number to decrement

Example

<h3>DecrementValue Example</h3>
<p>Returns the integer part of a number decremented by one.
<p>DecrementValue(0):
   <cfoutput>#DecrementValue(0)#</cfoutput>
<p>DecrementValue("1"):
   <cfoutput>#DecrementValue("1")#</cfoutput>
<p>DecrementValue(123.35):
   <cfoutput>#DecrementValue(123.35)#</cfoutput>


Decrypt

Description

Decrypts a string that is encrypted with the Encrypt function.

Return value

String, unencrypted.

Category

Other functions, String functions

Syntax

Decrypt(encrypted_string, seed)

See also

Duplicate , Encrypt

Parameters

Parameter | Description
encrypted_string | String or a variable that contains one. String to decrypt
seed | String. The 32-bit key that was used to encrypt the string.

Example

<!--- This example shows the use of Encrypt and Decrypt --->
<h3>Decrypt Example</h3>
<p>This function encrypts/decrypts a string. Enter a string and a key.
<cfif IsDefined("FORM.myString")>
   <cfset string = FORM.myString>
   <cfset key = FORM.myKey>
   <cfset encrypted = encrypt(string, key)>
   <cfset decrypted = decrypt(encrypted, key)>
   <cfoutput>
      <h4><B>The string:</B></h4> #string# <br>
      <h4><B>The key:</B></h4> #key#<br>
      <h4><B>Encrypted:</B></h4> #encrypted#<br>
      <h4><B>Decrypted:</B></h4> #decrypted#<br>
   </cfoutput>
</cfif>
<form action = "encrypt.cfm">
<p>Input your key:
<p><input type = "Text" name = "myKey" value = "foobar">
<p>Enter string to encrypt:
<p><textArea name = "myString" cols = "40" rows = "5" WRAP = "VIRTUAL">
This string will be encrypted (try typing some more)</textArea>
<input type = "Submit" value = "Encrypt my String">
</form>


DeleteClientVariable

Description

Deletes a client variable. (To test for the existence of a variable, use IsDefined.)

Return value

True, if the variable is successfully deleted; false, otherwise.

Category

Other functions

Syntax

DeleteClientVariable("name")

See also

GetClientVariablesList

History

New in ColdFusion MX: if the variable is not present, this function returns False. (In earlier releases, it threw an error.)

Parameters

Parameter | Description
name | Name of a client variable to delete, surrounded by double quotation marks

Example

<!--- This view-only example shows DeleteClientVariable --->
<h3>DeleteClientVariable Example</h3>

<p>This view-only example deletes a client variable called "User_ID", if it
   exists in the list of client variables returned by GetClientVariablesList.
<p>This example requires the existence of an Application.cfm file and client
   management to be in effect.
<!---
<cfset client.somevar = "">
<cfset client.user_id = "">
<p>Client variable list:<cfoutput>#GetClientVariablesList()#</cfoutput>
<cfif ListFindNoCase(GetClientVariablesList(), "User_ID") is not 0>

      <cfset temp = DeleteClientVariable("User_ID")>
      <p>Was variable "User_ID" Deleted? <cfoutput>#temp#</cfoutput>
</cfif>
<p>Amended Client variable list:<cfoutput>#GetClientVariablesList()#
</cfoutput>
--->


DirectoryExists

Description

Determines whether a directory exists.

Return value

Yes, if the specified directory exists; No, otherwise.

Category

System functions

Syntax

DirectoryExists(absolute_path)

See also

FileExists

Parameters

Parameter | Description
absolute_path | An absolute path

Example

<h3>DirectoryExists Example</h3>
<h3>Enter a directory to check for existence.</h2>
<form action = "directoryexists.cfm" method="post">
   <input type = "text" name = "yourDirectory">
   <br>
   <input type = "submit" name = "submit">
</form>

<cfif IsDefined("FORM.yourDirectory")>
   <cfif FORM.yourDirectory is not "">
   <cfset yourDirectory = FORM.yourDirectory>
      <cfif DirectoryExists(yourDirectory)>
         <cfoutput>
         <p>Your directory exists. Directory name: #yourDirectory#
         </cfoutput>
      <cfelse>
         <p>Your directory does not exist.</p>
      </cfif>
   </cfif>
</cfif>


DollarFormat

Description

Formats a string in U.S. format. (For other currencies, use LSCurrencyFormat or LSEuroCurrencyFormat .)

Return value

A number as a string, formatted with two decimal places, thousands separator, and dollar sign. If number is negative, the return value is enclosed in parentheses. If number is an empty string, returns zero.

Category

Display and formatting functions

Syntax

DollarFormat(number)

See also

DecimalFormat , NumberFormat

Parameters

Parameter | Description
number | Number to format

Example

<!--- This example shows the use of DollarFormat --->
<html>
<head>
<title>DollarFormat Example</title>
</head>
<body>
<h3>DollarFormat Example</h3>
<cfloop from = 8 to = 50 index = counter>
   <cfset full = counter>
   <cfset quarter = Evaluate(counter + (1/4))>
   <cfset half = Evaluate(counter + (1/2))>
   <cfset threefourth = Evaluate(counter + (3/4))>
   <cfoutput>
   <pre>
   bill   #DollarFormat(full)#   #DollarFormat(quarter)#
    #DollarFormat(half)# #DollarFormat(threefourth)#
   18% tip   #DollarFormat(Evaluate(full * (18/100)))#
    #DollarFormat(Evaluate(quarter * (18/100)))#
    #DollarFormat(Evaluate(half * (18/100)))#
    #DollarFormat(Evaluate(threefourth * (18/100)))#
   </pre>
   </cfoutput>
</cfloop>
</body>
</html>


Duplicate

Description

Returns a clone, also known as a deep copy, of a variable. There is no reference to the original variable.

Return value

A clone of a variable.

Category

Structure functions, System functions

Syntax

Duplicate(variable_name)

See also

StructCopy , other Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
variable_name | Name of a variable to duplicate

Usage

Use this function to duplicate complex structures, such as nested structures and queries.

Note: With this function, you cannot duplicate a COM, CORBA, or JAVA object returned from the cfobject tag or the CreateObject function. If an array element or structure field is a COM, CORBA, or JAVA object, you cannot duplicate the array or structure.

Example

<h3>Duplicate Example</h3>
<cfset s1 = StructNew()>
<cfset s1.nested  = StructNew()>
<cfset s1.nested.item = "original">
<cfset copy = StructCopy(s1)>
<cfset clone = Duplicate(s1)>
<!--- modify the original --->
<cfset s1.nested.item = "modified">
<cfoutput>
<p>The copy contains the modified value: #copy.nested.item#</p>
<p>The duplicate contains the original value: #clone.nested.item#</p>
</cfoutput>


Encrypt

Description

Encrypts a string. Uses a symmetric key-based algorithm, in which the same key is used to encrypt and decrypt a string. The security of the encrypted string depends on maintaining the secrecy of the key. Uses an XOR-based algorithm that uses a pseudo-random 32-bit key, based on a seed passed by the user as a function parameter.

Return value

String; can be much longer than the original string.

Category

Other functions, String functions

Syntax

Encrypt(string, seed)

See also

Decrypt

Parameters

Parameter | Description
string | String to encrypt
seed | String. Seed used to generate 32-bit encryption key.

Example

<h3>Encrypt Example</h3>
<p>This function allows for the encryption and decryption of a string.
Try it by entering a string and a key to see the results.
<cfif IsDefined("FORM.myString")>
  <cfset string = FORM.myString>
  <cfset key = FORM.myKey>
  <cfset encrypted = encrypt(string, key)>
  <cfset decrypted = decrypt(encrypted, key)>
     <cfoutput>
         <h4><B>The string:</B></h4> #string# <br>
         <h4><B>The key:</B></h4> #key#<br>
         <h4><B>Encrypted:</B></h4> #encrypted#<br>
         <h4><B>Decrypted:</B></h4> #decrypted#<br>
     </cfoutput>
</cfif>
<form action = "encrypt.cfm">
<p>Input your key:
<p><input type = "Text" name = "myKey" value = "foobar">
<p>Input your string to be encrypted:
<p><textArea name = "myString" cols = "40" rows = "5" WRAP = "VIRTUAL">
This string will be encrypted (try typing some more)
</textArea>
<input type = "Submit" value = "Encrypt my String">
</form>


Evaluate

Description

Evaluates one or more string expressions, dynamically, from left to right. (The results of an evaluation on the left can have meaning in an expression to the right.) Returns the result of evaluating the rightmost expression.

Return value

An object; the result of the evaluation(s).

Category

Dynamic evaluation functions

Syntax

Evaluate(string_expression1 [, string_expression2 [, … ] ] )

See also

DE , IIf

Parameters

Parameter | Description
string_expression1, string_expression2... | Expressions to evaluate

Usage

String expressions can be complex. If a string expression contains a single or double quotation mark, it must be escaped.

This function is useful for forming one variable from multiple variables. For example, to reference a column of the query qNames with a variable, var, using an index value to traverse rows, you could use the following code:

<cfset var=Evaluate("qNames.#colname#[#index#]")>

For more information, see Developing ColdFusion MX Applications with CFML.

Example

<!--- This shows the use of DE and Evaluate --->
<h3>Evaluate Example</h3>
<cfif IsDefined("FORM.myExpression")>
<h3>The Expression Result</h3>
<cftry>
<!--- Evaluate the expression --->
<cfset myExpression = Evaluate(FORM.myExpression)>
<!--- Use DE to output the value of the variable, unevaluated --->
<cfoutput>
<I>The value of the expression #Evaluate(DE(FORM.MyExpression))#
is #MyExpression#.</I>
</cfoutput>
...


Exp

Description

Calculates the exponent whose base is e that represents number. The constant e equals 2.71828182845904, the base of the natural logarithm. This function is the inverse of Log, the natural logarithm of number.

Return value

The constant e, raised to the power of number.

Category

Mathematical functions

Syntax

Exp(number)

See also

Log , Log10

Parameters

Parameter | Description
number | Exponent to apply to the base e

Usage

To calculate powers of other bases, use the exponentiation operator (^).

Example

<h3>Exp Example</h3>
<cfif IsDefined("FORM.Submit")>
   <cfoutput>
   <p>Your number, #FORM.number#
   <br>#FORM.number# raised to the E power: #exp(FORM.number)#
   <cfif FORM.number LTE 0>
      <br>You must enter a positive real number to see its natural logarithm
      <cfelse><br>
      The natural logarithm of #FORM.number#: #log(FORM.number)#
   </cfif>
   <cfif FORM.number LTE 0><br>
      You must enter a positive real number to see its logarithm to base 10
      <cfelse><br>
         The logarithm of #FORM.number# to base 10: #log10(FORM.number)#
</cfif>
</cfoutput>
</cfif>
<cfform action = "exp.cfm">
Enter a number to see its value raised to the E power,its natural logarithm,
and the logarithm of number to base 10.
<cfinput type = "Text" name = "number" message = "You must enter a number"
validate = "float" required = "No">
<input type = "Submit" name = "Submit">
</cfform>


ExpandPath

Description

Creates an absolute, platform-appropriate path that is equivalent to the value of relative_path, appended to the base path. This function (despite its name) can accept an absolute or relative path in the relative_path attribute

The base path is the currently executing page’s directory path. It is stored in pageContext.getServletContext().

Return value

A string. If the relative path contains a trailing forward slash or backward slash, the return value contains the same trailing character.

Category

System functions

Syntax

ExpandPath(relative_path)

See also

FileExists , GetCurrentTemplatePath , GetFileFromPath

History

New in ColdFusion MX: this function (despite its name) can accept an absolute or relative path in the relative_path attribute. To resolve a path, this function uses virtual mappings that are defined in the ColdFusion Administrator. This function does not reliably use virtual mappings that are defined in IIS, Apache, or other Web servers.

Parameters

Parameter | Description
relative_path | Relative or absolute directory reference or file name, within the current directory, (.\ and ..\) to convert to an absolute path. Can include forward backward slashes.

Usage

If the parameter or the returned path is invalid, the function throws an error.

These examples show the valid constructions of relative_path:

  • ExpandPath( "*.*")
  • ExpandPath( "/")
  • ExpandPath( "\")
  • ExpandPath( "/mycfpage.cfm")
  • ExpandPath( "mycfpage.cfm")
  • ExpandPath( "myDir/mycfpage.cfm")
  • ExpandPath( "/myDir/mycfpage.cfm")
  • ExpandPath( "../../mycfpage.cfm")

Example

<h3>ExpandPath Example - View Only</h3>
<!---
<cfset thisPath=ExpandPath("*.*")>
<cfset thisDirectory=GetDirectoryFromPath(thisPath)>
<cfoutput>
The current directory is: #GetDirectoryFromPath(thisPath)#

<cfif IsDefined("form.yourFile")>
<cfif form.yourFile is not "">
<cfset yourFile = form.yourFile>
   <cfif FileExists(ExpandPath(yourfile))>
   <p>Your file exists in this directory.  You entered
   the correct file name, #GetFileFromPath("#thisPath#/#yourfile#")#
   <CFELSE>
   <p>Your file was not found in this directory:
   <br>Here is a list of the other files in this directory:
   <!--- use CFDIRECTORY to give the contents of the
   snippets directory, order by name and size --->
   <CFDIRECTORY DIRECTORY="#thisDirectory#"
   NAME="myDirectory"
   SORT="name ASC, size DESC">
   <!--- Output the contents of the CFDIRECTORY as a CFTABLE --->
   <CFTABLE QUERY="myDirectory">
   <CFCOL HEADER="NAME:"
         TEXT="#Name#">
   <CFCOL HEADER="SIZE:"
         TEXT="#Size#">
   </CFTABLE>
   </cfif>
</cfif>
<cfelse>
<h3>Please enter a file name</h3>
</CFIF>
</cfoutput>

<FORM action="expandpath.cfm" METHOD="post">
<h3>Enter the name of a file in this directory <I>
<FONT SIZE="-1">(try expandpath.cfm)</FONT></I></h3>
<INPUT TYPE="Text" NAME="yourFile">
<INPUT TYPE="Submit" NAME="">
</form>
 --->


FileExists

Description

Determines whether a file exists.

Return value

Yes, if the file specified in the parameter exists; No, otherwise.

Category

System functions, Decision functions

Syntax

FileExists(absolute_path)

See also

DirectoryExists , ExpandPath , GetTemplatePath

Parameters

Parameter | Description
absolute_path | An absolute path

Example

<h3>FileExists Example</h3>

<cfset thisPath = ExpandPath("*.*")>
<cfset thisDirectory = GetDirectoryFromPath(thisPath)>
<cfoutput>
The current directory is: #GetDirectoryFromPath(thisPath)#
<cfif IsDefined("FORM.yourFile")>
<cfif FORM.yourFile is not "">
<cfset yourFile = FORM.yourFile>
   <cfif FileExists(ExpandPath(yourfile))>
   <p>Your file exists in this directory. You entered
   the correct file name, #GetFileFromPath("#thisPath#/#yourfile#")#
   <cfelse>


Find

Description

Finds the first occurrence of a substring in a string, from a specified start position. The search is case-sensitive.

Return value

A number; the position of substring in string; or 0, if substring is not in string.

Category

String functions

Syntax

Find(substring, string [, start ])

See also

FindNoCase , Compare , FindOneOf , REFind , Replace

Parameters

Parameter | Description
substring | A string or a variable that contains one. String for which to search.
string | A string or a variable that contains one. String in which to search.
start | Start position of search.

Example

<cfoutput>
   <cfset stringToSearch = "The quick brown fox jumped over the lazy dog.">
   #find("the",stringToSearch)#<br>
   #find("the",stringToSearch,35)#<br>
   #find("no such substring",stringToSearch)#<br>
   <br>
   #findnocase("the",stringToSearch)#<br>
   #findnocase("the",stringToSearch,5)#<br>
   #findnocase("no such substring",stringToSearch)#<br>
   <br>
   #findoneof("aeiou",stringToSearch)#<br>
   #findoneof("aeiou",stringToSearch,4)#<br>
   #findoneof("@%^*()",stringToSearch)#<br>
</cfoutput>


FindNoCase

Description

Finds the first occurrence of a substring in a string, from a specified start position. If substring is not in string, returns zero. The search is case-insensitive.

Return value

The position of substring in string; or 0, if substring is not in string.

Category

String functions

Syntax

FindNoCase(substring, string [, start ])

See also

Find , CompareNoCase , FindOneOf , REFind , Replace

Parameters

Parameter | Description
substring | A string or a variable that contains one. String for which to search.
string | A string or a variable that contains one. String in which to search.
start | Start position of search.

Example

   <cfset stringToSearch = "The quick brown fox jumped over the lazy dog.">
   #find("the",stringToSearch)#<br>
   #find("the",stringToSearch,35)#<br>
   #find("no such substring",stringToSearch)#<br>
   <br>
   #findnocase("the",stringToSearch)#<br>
   #findnocase("the",stringToSearch,5)#<br>
   #findnocase("no such substring",stringToSearch)#<br>
   <br>
   #findoneof("aeiou",stringToSearch)#<br>
   #findoneof("aeiou",stringToSearch,4)#<br>
   #findoneof("@%^*()",stringToSearch)#<br>


FindOneOf

Description

Finds the first occurrence of any one of a set of characters in a string, from a specified start position. The search is case-sensitive.

Return value

The position of the first member of set found in string; or 0, if no member of set is found in string.

Category

String functions

Syntax

FindOneOf(set, string [, start ])

See also

Find , Compare , REFind

Parameters

Parameter | Description
set | A string or a variable that contains one. String that contains one or more characters to search for.
string | A string or a variable that contains one. String in which to search.
start | Start position of search.

Example

   <cfset stringToSearch = "The quick brown fox jumped over the lazy dog.">
   #find("the",stringToSearch)#<br>
   #find("the",stringToSearch,35)#<br>
   #find("no such substring",stringToSearch)#<br>
   <br>
   #findnocase("the",stringToSearch)#<br>
   #findnocase("the",stringToSearch,5)#<br>
   #findnocase("no such substring",stringToSearch)#<br>
   <br>
   #findoneof("aeiou",stringToSearch)#<br>
   #findoneof("aeiou",stringToSearch,4)#<br>
   #findoneof("@%^*()",stringToSearch)#<br>


FirstDayOfMonth

Description

Determines the ordinal (day number, in the year) of the first day of the month in which a given date falls.

Return value

A number corresponding to a day-number in a year.

Category

Date and time functions

Syntax

FirstDayOfMonth(date)

See also

Day , DayOfWeek , DayOfWeekAsString , DayOfYear , DaysInMonth , DaysInYear

Parameters

Parameter
Description
date
  • Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<h3>FirstDayOfMonth Example</h3>

<cfoutput>
The first day of #MonthAsString(Month(Now()))#,
 #Year(Now())# was
  a #DayOfWeekAsString(DayOfWeek(FirstDayOfMonth(Now())))#,
   day #FirstDayOfMonth(Now())# of the year.
</cfoutput>


Fix

Description

Converts a real number to an integer.

Return value

If number is greater than or equal to 0, the closest integer less than number.

If number is less than 0, the closest integer greater than number.

Category

Mathematical functions

Syntax

Fix(number)

See also

Ceiling , Int , Round

Parameters

Parameter | Description
number | A number

Example

<h3>Fix Example</h3>
<p>Fix returns the closest integer less than the number if the number is greater
than or equal to 0. Fix returns the closest integer greater than the
number if number is less than 0.
<cfoutput>
<p>The fix of 3.4 is #fix(3.4)#
<p>The fix of 3 is #fix(3)#
<p>The fix of 3.8 is #fix(3.8)#
<p>The fix of -4.2 is #fix(-4.2)#
</cfoutput>


FormatBaseN

Description

Converts number to a string, in the base specified by radix.

Return value

String that represents number, in the base radix.

Category

Display and formatting functions, Mathematical functions, String functions

Syntax

FormatBaseN(number, radix)

See also

InputBaseN

Parameters

Parameter | Description
number | Number to convert
radix | Base of the result

Example

<h3>FormatBaseN Example</h3>
<p>Converts a number to a string in the base specified by Radix.
<p>
<cfoutput>
<br>FormatBaseN(10,2): #FormatBaseN(10,2)#
<br>FormatBaseN(1024,16): #FormatBaseN(1024,16)#
<br>FormatBaseN(125,10): #FormatBaseN(125,10)#
<br>FormatBaseN(10.75,2): #FormatBaseN(10.75,2)#
</cfoutput>
<h3>InputBaseN Example</h3>
<p>InputBaseN returns the number obtained by converting a string,
using base specified by Radix (an integer from 2 to 36).

<cfoutput>
<br>InputBaseN("1010",2): #InputBaseN("1010",2)#
<br>InputBaseN("3ff",16): #InputBaseN("3ff",16)#
<br>InputBaseN("125",10): #InputBaseN("125",10)#
<br>InputBaseN(1010,2): #InputBaseN(1010,2)#
</cfoutput>


GetAuthUser

Description

Gets the name of an authenticated user.

Return value

The name of an authenticated user.

Category

Authentication functions

Syntax

GetAuthUser()

See also

isUserInRole

History

New in ColdFusion MX: this function is new.

Example

<H3>GetAuthUser Example</H3>

<P>Authenticated User: <cfoutput>GetAuthUser()</cfoutput>


GetBaseTagData

Description

Used within a custom tag. Finds calling (ancestor) tag by name and accesses its data.

Return value

An object that contains data (variables, scopes, and so on) from an ancestor tag. If there is no ancestor by the specified name, or if the ancestor does not expose data (for example, cfif), an exception is thrown.

Category

Other functions

Syntax

GetBaseTagData(tagname [, instancenumber ] )

See also

GetBaseTagList

Parameters

Parameter | Req/Opt | Default | Description
tagname | Required |  | Ancestor tag name for which to return data
instancenumber | Optional | 1 (closest ancestor) | Number of ancestor levels to jump before returning data

Example

<!--- This example shows the use of GetBaseTagData
function. Typically used in custom tags.--->
...
<cfif trim(inCustomTag) neq "">
      <cfoutput>
         Running in the context of a custom
         tag named #inCustomTag#.<p>
      </cfoutput>
      <!--- Get the tag instance data --->
      <cfset tagData = GetBaseTagData(inCustomTag)>
      <!--- Find the tag's execution mode --->
      Located inside the
      <cfif tagData.thisTag.executionMode neq ’inactive’>
         template
      <cfelse>
         BODY
      </cfif>


GetBaseTagList

Description

Gets ancestor tag names, starting with the parent tag.

Return value

A comma-delimited list of uppercase ancestor tag names, as a string. The first list element is the current tag. If the current tag is nested, the next element is the parent tag. If the function is called for a top-level tag, it returns an empty string. If an ancestor does not expose data (see GetBaseTagData), its name might not be returned.

Category

Other functions

Syntax

GetBaseTagList()

See also

GetBaseTagData

Usage

This function does not display the following tags or end tags in the ancestor tag list:

  • cfif, cfelseif, cfelse
  • cfswitch
  • cfcase, cfdefaultcase
  • cfoutput
  • cftry, cfcatch

This function displays the following tags only under the following conditions:

  • cfloop: if there is a cfquery tag within it
  • cfoutput: if at least one of its children is a complex expression
  • cfprocessingdirective: if it has at least one other attribute besides pageencoding

Example

<!--- This example shows the use of GetBaseTagList function.
Typically used in custom tags. --->
...
<cfif thisTag.executionMode is "start">

   <!--- Get the tag context stack
   The list will look something like "CFIF,MYTAGNAME..." --->
   <cfset ancestorList = GetBaseTagList()>

   <!--- Output current tag name --->
   <cfoutput>This is custom tag #ListGetAt(ancestorList,2)#</cfoutput>
   <p>
   <!--- Determine whether this is nested inside a loop --->
   <cfset inLoop = ListFindNoCase(ancestorList, "cfloop")>
   <cfif inLoop neq 0>
      Running in the context of a cfloop tag.
   </cfif>


GetBaseTemplatePath

Description

Gets the absolute path of an application’s base page.

Return value

The absolute path of the application base page, as a string.

Category

Other functions, System functions

Syntax

GetBaseTemplatePath()

See also

GetCurrentTemplatePath , FileExists , ExpandPath

Example

<h3>GetBaseTemplatePath Example</h3>

<p>The template path of the current page is:
<cfoutput>#GetBaseTemplatePath()#</cfoutput>


GetClientVariablesList

Description

Finds the client variables to which a page has write access.

Return value

Comma-delimited list of non-read-only client variables, as a string.

Category

List functions, Other functions

Syntax

GetClientVariablesList()

See also

DeleteClientVariable

Usage

The list of variables returned by this function is compatible with ColdFusion list functions.

Example

<!--- this example is view only --->

<h3>GetClientVariablesList Example</h3>

<p>This view-only example deletes a client variable called "User_ID", if it exists
in the list of client variables returned by GetClientVariablesList().
<p>This example requires the existence of an Application.cfm file and that client
management be in effect.
<!---
<cfset client.somevar = "">
<cfset client.user_id = "">
<p>Client variable list:<cfoutput>#GetClientVariablesList()#</cfoutput>

<cfif ListFindNoCase(GetClientVariablesList(), "User_ID") is not 0>
<!--- delete that variable
   <cfset temp = DeleteClientVariable("User_ID")>
   <p>Was variable "User_ID" Deleted? <cfoutput>#temp#</cfoutput>
</cfif>

<p>Amended Client variable list:<cfoutput>#GetClientVariablesList()#
 </cfoutput>
--->


GetCurrentTemplatePath

Description

Gets the path of the page that calls this function.

Return value

The absolute path of the page that contains the call to this function, as a string.

Category

System functions

Syntax

GetCurrentTemplatePath()

See also

GetBaseTemplatePath , FileExists , ExpandPath

Usage

If the function call is made from a page included with a cfinclude tag, this function returns the page path of an included page. Contrast this with the GetBaseTemplatePath function, which returns the path of the top-level page, even if it is called from an included page.

Example

<!--- This example uses GetCurrentTemplatePath to show the
template path of the current page --->
<h3>GetCurrentTemplatePath Example</h3>

<p>The template path of the current page is:
<cfoutput>#GetCurrentTemplatePath()#</cfoutput>


GetDirectoryFromPath

Description

Extracts a filename and directory from an absolute path.

Return value

Absolute path, without the filename. The last character is a backward slash.

Category

System functions

Syntax

GetDirectoryFromPath(path)

See also

ExpandPath , GetFileFromPath

Parameters

Parameter | Description
path | Absolute path (drive, directory, filename, and extension)

Example

<h3>GetDirectoryFromPath Example</h3>
<cfset thisPath = ExpandPath("*.*")>
<cfset thisDirectory = GetDirectoryFromPath(thisPath)>
<cfoutput>
The current directory is: #GetDirectoryFromPath(thisPath)#
<cfif IsDefined("FORM.yourFile")>
   <cfif FORM.yourFile is not "">
      <cfset yourFile = FORM.yourFile>
         <cfif FileExists(ExpandPath(yourfile))>
         <p>Your file exists in this directory. You entered the correct file name,
   #GetFileFromPath("#thisPath#/#yourfile#")#
   <cfelse>
      <p>Your file was not found in this directory:
      <br>Here is a list of the other files in this directory:
      <!--- use cfdirectory show directory, order by name & size --->
      <cfdirectory directory = "#thisDirectory#"
         name = "myDirectory" SORT = "name ASC, size DESC">
      <!--- Output the contents of the cfdirectory as a CFTABLE --->
      <cftable query = "myDirectory">
         <cfcol header = "NAME:" text = "#Name#">
      <cfcol header = "SIZE:" text = "#Size#">
      </cftable>
      </cfif>
   </cfif>
<cfelse>
   <H3>Please enter a file name</H3>
   </cfif>
   </cfoutput>
   <form action="getdirectoryfrompath.cfm" METHOD="post">
      <H3>Enter the name of a file in this directory <I><FONT SIZE="-1">
(try expandpath.cfm)</FONT></I></H3>
      <input type="Text" NAME="yourFile">
      <input type="Submit" NAME="">
   </form> --->


GetException

Description

Used with the cftry and cfcatch tags. Retrieves a Java exception object from a Java object.

Return value

Any Java exception object raised by a previous method call on the Java object.

Category

System functions

Syntax

getException(object)

Parameters

Parameter | Description
object | A Java object.

Usage

ColdFusion stores a Java exception object for each method call on a Java object. Subsequent method calls reset the exception object. To get the current exception object, you must call getException on the Java object before other methods are invoked on it.

Example

<!--- Create the Java object reference --->
<cfobject action = create type = java class = primativetype name = myObj>
<!--- Calls the object's constructor --->
<cfset void  =  myObj.init()>
<cftry>
<cfset void  =  myObj.DoException() >
<Cfcatch type = "Any">
   <cfset exception = getException(myObj)>
<!--- user can call any valid method on the exception object--->
   <cfset message = exception.toString()>
   <cfoutput>
      Error<br>
      I got exception <br>
      <br> The exception message is: #message# <br>
   </cfoutput>
</cfcatch>
</cftry>


GetFileFromPath

Description

Extracts a filename from an absolute path.

Return value

File name, as a string.

Category

System functions

Syntax

GetFileFromPath(path)

See also

ExpandPath , GetCurrentTemplatePath

Parameters

Parameter | Description
path | Absolute path (drive, directory, filename, and extension)

Example

<h3>GetFileFromPath Example</h3>
<cfset thisPath  =  ExpandPath("*.*")>
<cfset thisDirectory  =  GetDirectoryFromPath(thisPath)>
<cfoutput>
The current directory is: #GetDirectoryFromPath(thisPath)#
<cfif IsDefined("FORM.yourFile")>
<cfif FORM.yourFile is not "">
<cfset yourFile = FORM.yourFile>
<cfif FileExists(ExpandPath(yourfile))>
      <p>Your file exists in this directory. You entered the correct file
name, #GetFileFromPath("#thisPath#/#yourfile#")#
   <cfelse>
      <p>Your file was not found in this directory:
      <br>Here is a list of the other files in this directory:
      <!--- use CFDIRECTORY to give the contents of the snippets
directory, order by name and size --->
      <CFDIRECTORY
         DIRECTORY = "#thisDirectory#"
         name = "myDirectory"
         SORT = "name ASC, size DESC">
      <!--- Output the contents of the CFDIRECTORY as a CFTABLE --->
      <CFTABLE QUERY = "myDirectory">
      <CFCOL HEADER = "NAME:" TEXT = "#Name#">
   <CFCOL HEADER = "SIZE:" TEXT = "#Size#">
...


GetFunctionList

Description

Displays a list of the functions that are available in ColdFusion.

Return value

A structure of functions.

Category

System functions

Syntax

GetFunctionList()

Example

<!----- This example shows the use of GetFunctionList. ---->
<cfset fList = GetFunctionList()>
<cfoutput>#StructCount(fList)# functions<br><br>
   </cfoutput>
<cfloop COLLECTION = "#fList#" ITEM = "key">
   <cfoutput>#key#<br>
   </cfoutput>
</cfloop>


GetHttpRequestData

Description

Makes HTTP request headers and body available to CFML pages. Useful for capturing SOAP request data, which can be delivered in an HTTP header.

Return value

A ColdFusion structure.

Category

System functions

Syntax

GetHttpRequestData()

Usage

The structure returned by this function contains the following entries:

Parameter | Description
headers | Structure that contains HTTP request headers as value pairs. Includes custom headers, such as SOAP requests.
content | Raw content from form submitted by client, in string or binary format. For content to be considered string data, the FORM request header "CONTENT_TYPE" must start with "text/" or be special case "application/x-www-form-urlencoded". Other types are stored as a binary object.
method | String that contains the CGI variable Request_Method.
protocol | String that contains the Server_Protocol CGI variable.

Note: To determine whether data is binary, use IsBinary(x.content).To convert data to a string value, if it can be displayed as a string, use toString(x.content).

The following example shows how this function can return HTTP header information.

Example

<cfset x = GetHttpRequestData()>
<cfoutput>
<table cellpadding = "2" cellspacing = "2">
  <tr>
    <td><b>HTTP Request item</b></td>
    <td><b>Value</b></td> </tr>
<cfloop collection = #x.headers# item = "http_item">
    <tr>
      <td>#http_item#</td>
      <td>#StructFind(x.headers, http_item)#</td>   </tr>
</cfloop>
<tr>
   <td>request_method</td>
   <td>#x.method#</td></tr>
<tr>
   <td>server_protocol</td>
   <td>#x.protocol#</td></tr>
</table>
<b>http_content --- #x.content#</b>
</cfoutput>


GetHttpTimeString

Description

Gets the current time, in the Universal Time code (UTC).

Return value

The time, as a string, according to the HTTP standard described in RFC 1123.

Category

Date and time functions, International functions

Syntax

GetHttpTimeString(date_time_object)

See also

GetLocale , GetTimeZoneInfo , SetLocale

Parameters

Parameter | Description
date_time_object | A ColdFusion date-time object string or Java Date object

Usage

The time in the returned string is UTC, consistent with the HTTP standard.

Example

<cfoutput>
#GetHttpTimeString("#Now()#")#<br>
</cfoutput>


GetK2ServerDocCount

Description

Determines the number of documents that can be searched by the ColdFusion registered K2 Server.

This function is used primarily by the ColdFusion Verity and K2Server Administrator pages. This function uses Verity K2Server Release K2.2.0.

Return value

The number of collection metadata items stored in Verity collections.

Category

Full-text search functions, Query functions

Syntax

GetK2ServerDocCount()

See also

GetK2ServerDocCountLimit

History

New in ColdFusion MX: This function is new.

Example

<cfoutput>GetK2ServerDocCount =
$*#GetK2ServerDocCount()#*$</cfoutput>


GetK2ServerDocCountLimit

Description

Gets the maximum number of documents that the ColdFusion registered K2 Server is permitted to return from a search.

This function is used primarily by the ColdFusion Verity and K2Server Administrator pages. This function uses Verity K2Server Release K2.2.0.

Return value

Number of collection metadata items that the K2 server permits, as an integer

Category

Full-text search functions, Query functions

Syntax

GetK2ServerDocCountLimit()

See also

GetK2ServerDocCount

History

New in ColdFusion MX: This function is new.

Usage

If a search generates a larger number of documents than the limit, ColdFusion puts a warning message in the Administrator and in the log file.

The restricted version of K2 Server version that is installed with ColdFusion has the following document search limits:

  • For ColdFusion MX Evaluation: 250,000
  • For ColdFusion MX Developer: 10,000
  • For ColdFusion MX Professional: 125,000
  • For ColdFusion MX Enterprise: 250,000
  • For ColdFusion MX with Macromedia Spectra: 750,000

K2Broker with ColdFusion MX has no limit.

Example

<cfoutput>GetK2ServerDocCountLimit =
$*#GetK2ServerDocCountLimit()#*$</cfoutput>


GetLocale

Description

Gets the current geographic/language locale value.

To set the default display format of date, time, number, and currency values in a ColdFusion application session, you use the SetLocale function.

Return value

The current locale value, as a string.

Category

Display and formatting functions, International functions, System functions

Syntax

GetLocale()

See also

SetLocale

History

New in ColdFusion MX: this function determines whether a locale value is set. (The value is set with the setlocale function.)

  • If the locale value is present, the function returns it.
  • If the locale has not been explicitly set, ColdFusion determines whether the default locale of the ColdFusion Server computer operating system is among the locale values it supports. (The default locale is stored in the user environment variables user.language and user.region.)
    • If the default locale value is supported, the function returns this value
    • If the default locale value is not supported, the function returns English (US). (The code is "en_us"). (When ColdFusion is started, it stores the supported locale values in the variable Server.ColdFusion.SupportedLocales.) ColdFusion sets the locale in the JVM to this value; it persists until the server is restarted or it is reset with the setlocale function.

Usage

This function does not access a web browser’s Accept-Language HTTP header setting.

Example

<h3>GetLocale Example</h3>
<p>The locale for this system is <cfoutput>#GetLocale()#</cfoutput>


GetMetaData

Description

Gets metadata (the methods, properties, and parameters of a component) associated with an object that is deployed on the ColdFusion server. This functionality, called introspection, lets applications dynamically determine how to use a component.

Return value

Key-value pairs, as a component descriptor data structure or as structured XML

Category

System functions

Syntax

GetMetaData(object)

or, if used within a ColdFusion component:

GetMetaData(this)

History

New in ColdFusion MX: This function is new.

Parameters

Parameter | Description
object | Reference to an object; use this attribute to call a function from a CFML page
this | Reference to an object; use this attribute to call a function from a component.

Usage

The this scope is available at runtime to the component body and to the invoked method’s function body. It is used to read and write variables that are present during the life of the component.

Component metadata contains at least the following keys:

  • name: the component name
  • path: an absolute path to the component
  • extends: ancestor component metadata
  • functions: an array of metadata for each component function

Other component attributes are returned as additional keys.

Function metadata contains at least the following keys:

  • name: the function name
  • parameters: an array of argument metadata

Other function attributes are returned as additional keys.

Argument metadata contains at least the following key:

  • name: the argument name

Other argument attributes are returned as additional keys.

Property metadata contains at least the following key:

  • name: the property name

Other property attributes are returned as additional keys.


GetMetricData

Description

Gets server performance metrics.

Return value

ColdFusion structure that contains metric data, depending on the mode value.

Category

System functions

Syntax

GetMetricData(mode)

History

New in ColdFusion MX: the cachepops parameter is deprecated. Do not use it in new applications. It might not work, and it might cause an error, in later releases.

Parameters

Parameter | Option | Description
mode | perf_monitor | Returns internal data, in a structure. To receive data, you must enable PerfMonitor in ColdFusion Administrator before executing the function. On Windows, this data is otherwise displayed in the Windows PerfMonitor.
 | simple_load | Returns an integer value that is computed from the state of the server's internal queues. Indicates the overall server load.
 | prev_req_time | Returns the time, in milliseconds, that it took the server to process the previous request.
 | avg_req_time | Returns the average time, in milliseconds, that it takes the server to process a request. Changing the setting to 0 prevents the server from calculating the average and removes overhead associated with gathering data. Default: 120 seconds.

Usage

If mode = "perf_monitor", the function returns a structure with these data fields:

Field | Description
InstanceName | The name of the ColdFusion server. Default: cfserver
PageHits | Number of HTTP requests received since ColdFusion Server was started.
ReqQueued | Number of HTTP requests in the staging queue, waiting for processing.
DBHits | Number of database requests since the server was started.
ReqRunning | Number of HTTP requests currently running. In the ColdFusion Administrator, you can set the maximum number of requests that run concurrently.
ReqTimedOut | Number of HTTP requests that timed out while in the staging queue or during processing.
BytesIn | Number of bytes in HTTP requests to ColdFusion Server
BytesOut | Number of bytes in HTTP responses from ColdFusion Server
AvgQueueTime | For the last two HTTP requests (current and previous), the average length of time the request waited in the staging queue.
AvgReqTime | For the last two HTTP requests (current and previous), the average length of time the server required to process the request
AvgDBTime | For the last two HTTP requests (current and previous), the average length of time the server took to process CFQueries in the request.
cachepops | This parameter is deprecated. Do not use it. ColdFusion automatically sets its value to -1.

Example

<!--- This example gets and displays metric data from Windows NT PerfMonitor --->
<cfset pmData = GetMetricData( "PERF_MONITOR" ) >
<cfoutput>
   Current PerfMonitor data is: <p>
   InstanceName:   #pmData.InstanceName# <p>
   PageHits:      #pmData.PageHits# <p>
   ReqQueued:       #pmData.ReqQueued# <p>
   DBHits:    #pmData.DBHits# <p>
   ReqRunning:       #pmData.ReqRunning# <p>
   ReqTimedOut: #pmData.ReqTimedOut# <p>
   BytesIn:       #pmData.BytesIn# <p>
   BytesOut:       #pmData.BytesOut# <p>
   AvgQueueTime: #pmData.AvgQueueTime# <p>
   AvgReqTime:       #pmData.AvgReqTime# <p>
   AvgDBTime:       #pmData.AvgDBTime# <p>
</cfoutput>


GetPageContext

Description

Gets the current ColdFusion MX PageContext object that provides access to page attributes and configuration, request and response objects.

Return value

The current ColdFusion MX Java PageContext object.

Category

System functions

Syntax

GetPageContext()

History

New in ColdFusion MX: This function is new.

Usage

The ColdFusion MX PageContext class is a wrapper class for the Java PageContext object that can resolve scopes and perform case-insensitive variable lookups.

The PageContext object exposes fields and methods that can be useful in J2EE integration. It includes the include and forward methods that provide the equivalent of the corresponding standard JSP tags. You use these methods to call JSP pages and servlets. For example, you use the following code in CFScript to include the JSP page hello.jsp and pass it a name parameter:

GetPageContext().include("hello.jsp?name=Bobby"); ===

For more information, see your Java Server Pages (JSP) documentation).

Example

<!--- this example shows using the page context to set a page
variable and access the language of the current locale --->
<cfset pc = GetPageContext()>

<cfset pc.setAttribute("name","John Doe")>
<cfoutput>name: #variables.name#<br></cfoutput>

<cfoutput>Language of the current locale is
#pc.getRequest().getLocale().getDisplayLanguage()#</cfoutput>>.


GetProfileSections

Description

Gets all the sections of an initialization file.

An initialization file assigns values to configuration variables, also known as entries, that are set when the system boots, the operating system comes up, or an application starts. An initialization file has the suffix INI; for example, boot.ini, Win32.ini.

Return value

An initialization file, as a struct whose format is as follows:

  • Each initialization file section name is a key in the struct
  • Each list of entries in a section of an initialization file is a value in the struct

If there is no value, returns an empty string.

Category

System functions

Syntax

GetProfileSections(iniFile)

See also

GetProfileString , SetProfileString

History

New in ColdFusion MX: This function is new.

Parameters

Parameter | Description
iniFile | Absolute path (drive, directory, filename, extension) of initialization file; for example, C:\boot.ini


GetProfileString

Description

Gets an initialization file entry.

An initialization file assigns values to configuration variables, also known as entries, that are set when the system boots, the operating system comes up, or an application starts. An initialization file has the suffix INI; for example, boot.ini, Win32.ini.

Return value

An entry in an initialization file, as a string. If there is no value, returns an empty string.

Category

System functions

Syntax

GetProfileString(iniPath, section, entry)

See also

GetProfileSections , GetProfileString , SetProfileString

Parameters

Parameter | Description
iniPath | Absolute path (drive, directory, filename, extension) of initialization file; for example, C:\boot.ini
section | Section of initialization file from which to extract information
entry | Name of value to get

Example

<h3>GetProfileString Example</h3>
Uses GetProfileString to get the value of timeout in an initialization file. Enter
the full path of your initialization file, and submit the form.
<!--- If the form was submitted, it gets the initialization path and timeout value
specified in the form --->
<cfif Isdefined("Form.Submit")>
   <cfset IniPath = FORM.iniPath>
   <cfset Section = "boot loader">
   <cfset timeout = GetProfileString(IniPath, Section, "timeout")>
   <h4>Boot Loader</h4>
   <!--- If no entry in an initialization file, nothing displays --->
   <p>Timeout is set to: <cfoutput>#timeout#</cfoutput>.</p>
</cfif>
<form action = "getprofilestring.cfm">
<table cellspacing = "2" cellpadding = "2" border = "0">
   <tr>
       <td>Full Path of Init File</td>
       <td><input type = "Text" name = "IniPath" value = "C:\myboot.ini">
      </td>
   </tr>
   <tr>
    <td><input type = "Submit" name = "Submit" value = "Submit"></td>
    <td></td>
   </tr></table>
</form>


GetServiceSettings

Description

Gets the internal Services settings that are available for access; for example, a list of registered ColdFusion data sources.

Services settings include the following:

  • Data items that, in ColdFusion 5 and earlier releases, were stored in the registry
  • New data items that ColdFusion MX and later releases use
  • Internal data items that are not accessible with this function

Return value

The internal data structures that contain Services settings.

Category

System functions

Syntax

GetServiceSettings()

History

New in ColdFusion MX: This function is new.


GetTempDirectory

Description

Gets the path of the directory that ColdFusion uses for temporary files. The directory depends on the account under which ColdFusion is running and other factors. Before using this function in an application, test to determine the directory it returns under your account.

Return value

The absolute pathname of a directory, including a trailing slash, as a string.

Category

System functions

Syntax

GetTempDirectory()

See also

GetTempFile

History

New in ColdFusion MX: On Windows, this function returns the temporary directory of the embedded Java application server. On other platforms, it returns the temporary directory of the operating system.

Example

<h3>GetTempDirectory Example</h3>

<p>The temporary directory for this ColdFusion server is
<cfoutput>#GetTempDirectory()#</cfoutput>.
<p>We have created a temporary file called:
<cfoutput>#GetTempFile(GetTempDirectory(),"testFile")#</cfoutput>


GetTempFile

Description

Creates a temporary file in a directory whose name starts with (at most) the first three characters of prefix.

Return value

Name of a temporary file, as a string.

Category

System functions

Syntax

GetTempFile(dir, prefix)

See also

GetTempDirectory

Parameters

Parameter | Description
dir | Directory name
prefix | Prefix of a temporary file to create in the directory dir

Example

<h3>GetTempFile Example</h3>
<p>The temporary directory for this ColdFusion Server is
<cfoutput>#GetTempDirectory()#</cfoutput>.
<p>We have created a temporary file called:
<cfoutput>#GetTempFile(GetTempDirectory(),"testFile")#</cfoutput>


GetTemplatePath

Description

This function is deprecated. Use the GetBaseTemplatePath function instead.

Gets the absolute path of an application’s base page.

History

New in ColdFusion MX: This function is deprecated. Do not use it in new applications. It might not work, and it might cause an error, in later releases.


GetTickCount

Description

Determines the differences between the results of GetTickCount at successive points of page processing.

Return value

An integer value

Category

Date and time functions

Syntax

GetTickCount()

Usage

This function is useful for timing CFML code segments or other page processing elements.

Example

<!--- Setup timing test --->
<cfset iterationCount = 1000>
<!--- Time an empty loop with this many iterations --->
<cfset tickBegin = GetTickCount()>
<cfloop Index = i From = 1 To = #iterationCount#></cfloop>
<cfset tickEnd = GetTickCount()>
<cfset loopTime = tickEnd - tickBegin>

<!--- Report --->
<cfoutput>Loop time (#iterationCount# iterations) was: #loopTime#
    milliseconds</cfoutput>


GetTimeZoneInfo

Description

Gets local time zone information for the computer on which it is called, relative to Universal Time Coordinated (UTC). UTC is the mean solar time of the meridian of Greenwich, England, used as the basis for calculating standard time throughout the world.

ColdFusion stores date and time values as date-time objects: real numbers on a universal time line. It converts an object to a time zone when it formats an object; it converts a date/time value from a time zone to a real number when it parses a value.

Return value

Structure that contains these elements and keys:

  • utcTotalOffset: offset of local time, in seconds, from UTC
    • A plus sign indicates a time zone west of UTC (such as a zone in North America)
    • A minus sign indicates a time zone east of UTC (such as a zone in Germany)
  • utcHourOffset: offset, in hours of local time, from UTC
  • utcMinuteOffset: offset, in minutes, beyond the hours offset. For North America, this is 0. For countries that are not exactly on the hour offset, the number is between 0 and 60. For example, standard time in Adelaide, Australia is offset 9 hours and 30 minutes from UTC.
  • isDSTOn: True, if Daylight Savings Time (DST) is on in the host; False, otherwise

Category

Date and time functions, International functions

Syntax

GetTimeZoneInfo()

See also

DateConvert , CreateDateTime , DatePart

Example

<h3>GetTimeZoneInfo Example</h3>
<!--- This example shows the use of GetTimeZoneInfo --->
<cfoutput>
The local date and time are #now()#.
</cfoutput>

<cfset info = GetTimeZoneInfo()>
<cfoutput>
<p>Total offset in seconds is #info.utcTotalOffset#.</p>
<p>Offset in hours is #info.utcHourOffset#.</p>
<p>Offset in minutes minus the offset in hours is
   #info.utcMinuteOffset#.</p>
<p>Is Daylight Savings Time in effect? #info.isDSTOn#.</p>
</cfoutput>


GetToken

Description

Determines whether a token of the list in the delimiters parameter is present in a string.

Return value

The token found at position index of the string, as a string. If index is greater than the number of tokens in the string, returns an empty string.

Category

String functions

Syntax

GetToken(string, index [, delimiters ])

See also

Left , Right , Mid , SpanExcluding , SpanIncluding

Parameters

Parameter
Description
string
A string or a variable that contains one. String in which to search.
index
Positive integer or a variable that contains one. The position of a token.
delimiters
A string or a variable that contains one. A delimited list of delimiters. Elements may consist of multiple characters.
Default list of delimiters: space character, tab character, newline character; or their codes: "chr(32)", "chr(9)", chr(10).
Default list delimiter: comma character.

Usage

The following examples show how this function works.

Example A: Consider the following code:

GetToken("red,blue:;red,black,tan:;red,pink,brown:;red,three", 2, ":;")

This function call requests element number 2 from the string, using the delimiter ";:". The output is as follows:

red,black,tan

Example B: Consider the following code:

<cfset mystring = "four,"
& #chr(32)# & #chr(9)# & #chr(10)#
& ",five, nine,zero:;"
& #chr(10)#
& "nine,ten:, eleven:;twelve:;thirteen,"
& #chr(32)# & #chr(9)# & #chr(10)#
& ",four">
<cfoutput>
#mystring#<br><br>
</cfoutput>

The output is as follows:

four,
,five, nine,zero:;
nine,ten:, eleven:;twelve:;thirteen,
,four

The gettoken function recognizes explicit spaces, tabs, or newline characters as the parameter delimiters (To specify a space character, the code is chr(32); a tab character, chr(9); and a newline character, chr(10).)

In the example string mystring, there is:

  • A forced space between the substrings "four," and ",five"
  • A literal space between "five," and "nine"
  • A literal space between "ten:," and "eleven,"
  • A forced space between "thirteen," and ",four"

In the following call against mystring, no spaces are specified in delimiters (it is omitted), so the function uses the space character as the string delimiter:

<br>
<cfoutput>
gettoken(mystring, 3) is : #gettoken(mystring, 3)#
</cfoutput><br>

The output of this code is as follows:

gettoken(mystring, 3) is : nine,zero:;

The function finds the third delimiter, and returns the substring just before it that is between the second and third delimiter. This substring is "nine,zero:;".

Example C: Consider the following code:

<cfset mystring2 = "four,"
&#chr(9)# & #chr(10)#
& ",five,nine,zero:;"
& #chr(10)#
& "nine,ten:,eleven:;twelve:;thirteen,"
& #chr(9)# & #chr(10)# & ",four">
<cfoutput>
#mystring2#<br>
</cfoutput>

The output is as follows:

four,
,five,nine,zero:;
nine,ten:,eleven:;twelve:;thirteen,
,four

The following is a call against mystring2:

<cfoutput>
gettoken(mystring2, 2) is : #gettoken(mystring2, 2)#
</cfoutput>

The output is as follows:

gettoken(mystring2, 2) is : ,five,nine,zero:;

The function finds the second delimiter, and returns the substring just before it that is between the first and second delimiter. This substring is ",five,nine,zero:;".

Example

<h3>GetToken Example</h3>
<cfif IsDefined("FORM.yourString")>
<!--- set delimiter --->
<cfif FORM.yourDelimiter is not "">
      <cfset yourDelimiter = FORM.yourDelimiter>
   <cfelse>
      <cfset yourDelimiter = " ">
</cfif>
<!--- check whether number of elements in list is greater than or
equal to the element sought to return --->
<cfif ListLen(FORM.yourString, yourDelimiter) GTE FORM.returnElement>
   <cfoutput>
   <p>Element #FORM.ReturnElement# in #FORM.yourString#,
   delimited by "#yourDelimiter#"
   <br>is:#GetToken(FORM.yourString, FORM.returnElement, yourDelimiter)#
   </cfoutput>
...


Hash

Description

Converts a variable-length string to a 32-byte, hexadecimal string, using the MD5 algorithm. (It is not possible to convert the hash result back to the source string.)

Return value

32-byte, hexadecimal string

Category

Conversion functions, Other functions, String functions

Syntax

Hash(string)

Parameters

Parameter | Description
string | A string or a variable that contains one.

Usage

The result is useful for comparison and validation. For example, a developer can store the hash of a password in a database without exposing the password. The developer can check the validity of the password with the following code:

<cfif hash(form.password) is not myQuery.passwordHash>
  <cflocation url = "unauthenticated.cfm">
</cfif>

Example

<!--- How to use Hash for password validation. This assumes that UserID
value is passed to this page with a URL parameter. --->
<h3>Hash Example</h3>

<cfquery name = "CheckPerson" datasource = "UserData">
   SELECT PasswordHash
   FROM SecureData
   WHERE UserID = <cfqueryparam value = "#UserID#"
      cfsqltype = "CF_SQL_CHARVAR">
</cfquery>

<cfif Hash(form.password) is not checkperson.passwordHash>
  <cflocation url = "unauthenticated.cfm">
<cfelse>
   ...
</cfif>


Hour

Description

Gets the current hour of the day.

Return value

Ordinal value of the hour, in the range 0 - 23.

Category

Date and time functions

Syntax

Hour(date)

See also

DatePart , Minute , Second

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<!--- This example shows the use of Hour, Minute, and Second --->
<h3>Hour Example</h3>
<cfoutput>
The time is currently #TimeFormat(Now())#.
We are in hour #Hour(Now())#, Minute #Minute(Now())#
and Second #Second(Now())# of the day.
</cfoutput>


HTMLCodeFormat

Description

Replaces special characters in a string with their HTML-escaped equivalents and inserts <pre> and </pre> tags at the beginning and end of the string.

Return value

HTML-escaped string string, enclosed in <pre> and </pre> tags. Returns are removed from string. Special characters (> < " &) are escaped.

Category

Display and formatting functions

Syntax

HTMLCodeFormat(string [, version ])

See also

HTMLEditFormat

Parameters

Parameter
Description
string
A string or a variable that contains one.
version
HTML version to use:
  • -1: The latest implementation of HTML
  • 2.0: HTML 2.0 (Default)
  • 3.2: HTML 3.2

Example

<!--- Shows the use of HTMLCodeFormat and HTMLEditFormat --->
<h3>HTMLCodeFormat Example</h3>
<form action = "HTMLcodeformat.cfm">
   Try entering a URL for the tag to return in HTMLCodeFormat and HTMLEditFormat:
   <input type = "Text" size = 25 name = "urladdress"
value = "http://www.macromedia.com">
   <input type = "Submit" name = "" value = "get page">
</form>

<!--- sets a default value for a url to retrieve --->
<cfparam name = "urladdress" default = "http://localhost/cfdocs/index.htm">

<!--- if we passed a url address in FORM, we display it --->
<cfif IsDefined("FORM.urladdress") is True>

<!--- do simple error check to avoid crashing the tag --->
   <cfif Trim(Form.urladdress) is "" or Trim(Form.urladdress) is "http://">
<!--- if error condition tripped, set alternative --->
      <cfset urlAddress = "http://localhost/cfdocs/index.htm">
      <h4>because you entered no url or an empty string, the tag will
return this address: http://localhost/cfdocs/index.htm</h4>
   <cfelse>
<!--- otherwise use address passed from form --->
      <cfset urlAddress = FORM.urladdress>
   </cfif>
<!--- use the CFHTTP tag to get the file content represented by urladdress --->
      <CFHTTP URL = "#urladdress#"
         method = "GET"
         RESOLVEURL = YES>
      </CFHTTP>

<cfelse>
<!--- the first time through, retrieve a URL that we know exists --->
<CFHTTP URL = "http://localhost/cfdocs/index.htm"
   method = "GET"
   RESOLVEURL = YES>
</CFHTTP>
</cfif>

<!--- Now, output the file, including the mimetype and content --->
<h3>Show the file</h3>

<cfoutput>
<p>Here is an example of 255 characters from your file output in HTMLCodeFormat:
<p>#HTMLCodeFormat(Mid(CFHTTP.FileContent,1,255))#

<p>Here is an example of 255 characters from your file output in HTMLEditFormat:
<p>#HTMLEditFormat(Mid(CFHTTP.FileContent,1,255))#
</cfoutput>


HTMLEditFormat

Description

Replaces special characters in a string with their HTML-escaped equivalents.

Return value

HTML-escaped string string. Returns are removed from string. Special characters (for example < " &) are escaped.

Category

Display and formatting functions

Syntax

HTMLEditFormat(string [, version ])

See also

HTMLCodeFormat

Parameters

Parameter
Description
string
A string or a variable that contains one.
version
HTML version to use.
  • -1: The latest implementation of HTML
  • 2.0: HTML 2.0 (Default)
  • 3.2: HTML 3.2

Usage

This function increases the length of a string. This can cause unpredictable results when performing certain string functions (Left, Right, and Mid, for example) against the expanded string.

Example

<!--- Shows the use of HTMLCodeFormat and HTMLEditFormat --->
<h3>HTMLEditFormat Example</h3>
<form action = "HTMLeditformat.cfm">
   Try entering a URL for the tag to return in HTMLCodeFormat and HTMLEditFormat:
   <input type = "Text" size = 25 name = "urladdress"
value = "http://www.macromedia.com">
   <input type = "Submit" name = "" value = "get page">
</form>

<!--- sets a default value for a url to retrieve --->
<cfparam name = "urladdress" default = "http://localhost/cfdocs/index.htm">

<!--- if we have passed a url address in the FORM, we want to
display the passed address --->
<cfif IsDefined("FORM.urladdress") is True>
<!--- do simple error check to avoid crashing the tag --->
   <cfif Trim(Form.urladdress) is "" or Trim(Form.urladdress) is "http://">
<!--- if error condition tripped, set alternative --->
      <cfset urlAddress = "http://localhost/cfdocs/index.htm">
      <h4>because you entered no url or an empty string, the tag will
return the following address:
      http://localhost/cfdocs/index.htm</h4>

   <cfelse>
<!--- otherwise use address passed from form --->
      <cfset urlAddress = "#FORM.urladdress#">
   </cfif>
<!--- now use the CFHTTP tag to get the file content represented by urladdress --->
      <CFHTTP URL = "#urladdress#"
         method = "GET"
         RESOLVEURL = YES>
      </CFHTTP>
<cfelse>
<!--- the first time through, retrieve a URL that we know exists --->

<CFHTTP URL = "http://localhost/cfdocs/index.htm"
   method = "GET"
   RESOLVEURL = YES>
</CFHTTP>
</cfif>

<!--- Now, output the file, including the mimetype and content --->
<h3>Show the file</h3>

<cfoutput>
<p>Here is an example of 255 characters from your file
output in HTMLCodeFormat:
<p>#HTMLCodeFormat(Mid(CFHTTP.FileContent,1,255))#

<p>Here is an example of 255 characters from your file
output in HTMLEditFormat:
<p>#HTMLEditFormat(Mid(CFHTTP.FileContent,1,255))#
</cfoutput>


IIf

Description

Evaluates a Boolean conditional dynamic expression. Depending on whether the expression is true or false, dynamically evaluates one of two string expressions and returns the result. This function is convenient for incorporating a cfif tag in-line in HTML.

For general conditional processing, see cfif. For error handling, see cftry. For more information, see Developing ColdFusion MX Applications with CFML.

Return value

If result is True, returns the value of Evaluate(string_expression1); otherwise, returns the value of Evaluate(string_expression2).

Category

Decision functions, Dynamic evaluation functions

Syntax

IIf(condition, string_expression1, string_expression2)

See also

DE , Evaluate

Parameters

Parameter | Description
condition | An expression that can be evaluated as a Boolean.
string_expression1 | A string or a variable that contains one. Expression to evaluate and return if condition is True.
string_expression2 | A string or a variable that contains one. Expression to evaluate and return if condition is False.

Usage

The IIf function is a shortcut for the following construct:

<cfif condition>
   <cfset result = Evaluate(string_expression1)>
<cfelse>
   <cfset result = Evaluate(string_expression2)>
</cfif>

The expressions string_expression1 and string_expression2 must be string expressions, so that they are not evaluated immediately as the parameters of IIf. For example:

IIf(y is 0, DE("Error"), x/y)

If y = 0, this generates an error, because the third expression is the value of x/0 (invalid expression).

ColdFusion evaluates string_expression1 and string_expression2. To return the string itself, use the DE function.

Note: If you use pound signs (#) in string_expression1 or string_expression2, ColdFusion evaluates the part of the expression in pound signs first. If you misuse the pound signs, you can cause unexpected results from the IIf function. For example, if you use pound signs around the whole expression in string_expression1, and if there is an undefined variable in string_expression1, the function might fail, with the error 'Error Resolving Parameter,'

If a variable is undefined, ColdFusion throws an error when it processes this function. The following example shows this problem:

#IIf(IsDefined("Form.Deliver"), DE(Form.Deliver), DE("no"))#

This returns "Error resolving parameter FORM.DELIVER".

To avoid this problem, use the DE and Evaluate functions in code such as the following:

#IIf(IsDefined("Form.Deliver"), Evaluate(DE("Form.Deliver")), DE("no"))#

This returns "no"; ColdFusion does not throw an error.

In the following example, LocalVar is undefined; however, if you omit pound signs around LocalVar, the code works properly:

<cfoutput>
   #IIf(IsDefined("LocalVar"), "LocalVar",
      DE("The variable is not defined."))#
</cfoutput>

The output is:

   The variable is not defined.

The pound signs around LocalVar in the following code cause it to fail with the error message 'Error Resolving Parameter', because ColdFusion never evaluates the original condition IsDefined("LocalVar").

Here is another example:

<cfoutput>
#IIf(IsDefined("LocalVar"), DE("#LocalVar#"), DE("The variable is not defined."))#
</cfoutput>

The error message would be as follows:

   Error resolving parameter LOCALVAR

The DE function has no effect on the evaluation of LocalVar, because the pound signs cause it to be evaluated immediately.

Example

<h3>IIf Function Example</h3>
<p>IIf evaluates a condition, and does an Evaluate on string
expression 1 or string expression 2 depending on the Boolean
outcome <I>(True: run expression 1; False: run expression 2)</I>.</p>
<p>The result of the expression
IIf( Hour(Now()) GTE 12,
   DE("It is afternoon or evening"),
   DE("It is morning"))
is:<br><b>
<cfoutput>
   #IIf( Hour(Now()) GTE 12,
DE("It is afternoon or evening"),
DE("It is morning"))#
</cfoutput>
</b>


IncrementValue

Description

Adds one to an integer.

Return value

The integer part of number, incremented by one.

Category

Mathematical functions

Syntax

IncrementValue(number)

See also

DecrementValue

Parameters

Parameter | Description
number | Number to increment

Example

<h3>IncrementValue Example</h3>
<p>Returns the integer part of a number incremented by one.
<p>IncrementValue(0): <cfoutput>#IncrementValue(0)#</cfoutput>
<p>IncrementValue("1"): <cfoutput>#IncrementValue("1")#</cfoutput>
<p>IncrementValue(123.35): <cfoutput>#IncrementValue(123.35)#</cfoutput>


InputBaseN

Description

Converts string, using the base specified by radix, to an integer.

Return value

A number in the range 2-36, as a string.

Category

Mathematical functions

Syntax

InputBaseN(string, radix)

See also

FormatBaseN

Parameters

Parameter | Description
string | A string or a variable that contains one. String that represents a number, in the base specified by radix.
radix | Base of the number represented by string, in the range 2 -- 36.

Example

<h3>InputBaseN Example</h3>

<p>FormatBaseN converts a number to a string in the base specified by Radix.
<p>
<cfoutput>
<br>FormatBaseN(10,2): #FormatBaseN(10,2)#
<br>FormatBaseN(1024,16): #FormatBaseN(1024,16)#
<br>FormatBaseN(125,10): #FormatBaseN(125,10)#
<br>FormatBaseN(10.75,2): #FormatBaseN(10.75,2)#
</cfoutput>
<h3>InputBaseN Example</h3>
<p>InputBaseN returns the number obtained by converting a string,
using the base specified by Radix,.
<cfoutput>
<br>InputBaseN("1010",2): #InputBaseN("1010",2)#
<br>InputBaseN("3ff",16): #InputBaseN("3ff",16)#
<br>InputBaseN("125",10): #InputBaseN("125",10)#
<br>InputBaseN(1010,2): #InputBaseN(1010,2)#
</cfoutput>


Insert

Description

Inserts a substring in a string after a specified character position. If position = 0, prefixes the substring to the string.

Return value

A string.

Category

String functions

Syntax

Insert(substring, string, position)

See also

RemoveChars , Len

Parameters

Parameter | Description
substring | A string or a variable that contains one. String to insert.
string | A string or a variable that contains one. String into which to insert substring.
position | Integer or variable; position in string after which to insert substring.

Example

<h3>Insert Example</h3>

<cfif IsDefined("FORM.myString")>
   <!--- if the position is longer than the length of the string, err --->
   <cfif FORM.insertPosition GT Len(MyString)>
      <cfoutput>
      <p>This string only has #Len(MyString)# characters; therefore,
you cannot insert the substring       #FORM.mySubString# at position
#FORM.insertPosition#.
      </cfoutput>
   </cfif>
<cfelse>
   <cfoutput>
   <p>You inserted the substring #FORM.MySubstring# into the string
#FORM.MyString#, resulting in the following string:
<br>#Insert(FORM.MySubString, FORM.myString,
FORM.insertposition)#
   </cfoutput>
</cfif>


Int

Description

Calculates the closest integer that is smaller than number.

Return value

An integer, as a string.

Category

Mathematical functions

Syntax

Int(number)

See also

Ceiling , Fix , Round

Parameters

Parameter | Description
number | Real number to round down to an integer

Example

<h3>Int Example</h3>
<p>Int returns the closest integer smaller than a number.

<p>Int(11.7) : <cfoutput>#Int(11.7)#</cfoutput>
<p>Int(-11.7) : <cfoutput>#Int(-11.7)#</cfoutput>
<p>Int(0) : <cfoutput>#Int(0)#</cfoutput>


IsArray

Description

Determines whether a value is an array.

Return value

True, if value is an array, or a query column object.

Category

Array functions, Decision functions

Syntax

IsArray(value [, number ])

See also

Array functions

History

New in ColdFusion MX: if the value attribute contains a reference to a query result column, this function returns True. For example: isArray(MyQuery[’Column1’]) returns True. (In earlier releases, it returns False.)

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
value | Variable or array name
number | Dimension; function tests whether the array has exactly this dimension

Usage

This function evaluates a Java array object, such as vector object, as having one dimension.

Example

<h3>IsArray Example</h3>

<!--- Make an array --->
<cfset MyNewArray = ArrayNew(1)>
<!--- set some elements --->
<cfset MyNewArray[1] = "element one">
<cfset MyNewArray[2] = "element two">
<cfset MyNewArray[3] = "element three">
<!--- is it an array? --->
<cfoutput>
   <p>Is this an array? #IsArray(MyNewArray)#
   <p>It has #ArrayLen(MyNewArray)# elements.
   <p>Contents: #ArrayToList(MyNewArray)#
</cfoutput>


IsAuthenticated

Description

This function is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML.

History

New in ColdFusion MX: This function is obsolete. It does not work in ColdFusion MX and later ColdFusion releases.


IsAuthorized

Description

This function is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML

History

New in ColdFusion MX: This function is obsolete. It does not work in ColdFusion MX and later releases.


IsBinary

Description

Determines whether a value is stored as binary data.

Return value

True, if the value is binary; False, otherwise. Returns the value in Base64 format.

Category

Decision functions

Syntax

IsBinary(value)

See also

ToBinary , ToBase64 , IsNumeric , YesNoFormat

Parameters

Parameter | Description
value | Number or string

Example

<!--- This example shows the use of IsBinary. It assumes that another page in a
syndication program passed this page the value of the variable data_var,
which can hold character or binary data. This example checks whether
data_var is binary; if so, it converts the data to Base64 data. --->
<h3>IsBinary Example</h3>

<!--- Check whether syndicated data is in binary form. If so, convert to Base64
so it can be viewed as printable characters. --->
<cfif IsBinary(data_var)>
   <cfset Base64data = ToBase64(data_var)
</cfif>


IsBoolean

Description

Determines whether a value can be converted to Boolean.

Return value

True, if value can be converted to Boolean; False, otherwise.

Category

Decision functions

Syntax

IsBoolean(value)

See also

IsNumeric , YesNoFormat

Parameters

Parameter | Description
value | Number or string

Example

<h3>IsBoolean Example</h3>

<cfif IsDefined("FORM.theTestValue")>
   <cfif IsBoolean(FORM.theTestValue)>
      <h3>The expression <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is
Boolean</h3>
   <cfelse>
      <h3>The expression <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is not
Boolean</h3>
   </cfif>
</cfif>

<form action = "isBoolean.cfm">
<p>Enter an expression, and discover whether it can be evaluated to a
Boolean value.

<input type = "Text" name = "TheTestValue" value = "1">
<input type = "Submit" value = "Is it Boolean?" name = "">
</form>


IsCustomFunction

Description

Determines whether a function be called as a custom function. Displays information about a user-defined function.

Return value

True, if name can be called as a custom function; False, otherwise.

Category

Decision functions

Syntax

IsCustomFunction("name")

Parameters

Parameter | Description
name | Name of a custom function, between quotation marks.

Usage

The following example generates the following output:

realUDF is a function.

Example

<h3>IsCustomFunction</h3>
<cfscript>
function realUDF() {
   return 1;
}
</cfscript>
<CFSET X = 1>
<!--- example that  fails completely --->
<CFIF IsDefined("Foo") AND IsCustomFunction("Foo")>
   Foo is a UDF.<br>
</CFIF>

<!--- Example that passes, for X, but fails on IsCustomFunction --->
<CFIF IsDefined("X") AND IsCustomFunction("X")>
   X is a UDF.<br>
</CFIF>
<!--- Example that passes --->
<CFIF IsDefined("realUDF") AND IsCustomFunction("realUDF")>
   realUDF is a function.<br>
</CFIF>


IsDate

Description

Determines whether a string or Java object can be converted to a date/time value.

Return value

True, if string can be converted to a date/time value; otherwise, False. ColdFusion converts the Boolean return value to its string equivalent, "Yes" or "No."

Category

Date and time functions, Decision functions

Syntax

IsDate(string)

See also

CreateDateTime , IsNumericDate , LSDateFormat , LSIsDate , ParseDateTime

Parameters

Parameter | Description
string | A string or a variable that contains one.

Usage

This function checks only a U.S. date format. For other date support, see LSDateFormat.

A date/time object falls in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Example

<h3>IsDate Example</h3>
<cfif IsDefined("FORM.theTestValue")>
   <cfif IsDate(FORM.theTestValue)>
   <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput>
    is a valid date</h3>
   <cfelse>
   <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput>
    is not a valid date</h3>
   </cfif>
</cfif>
<form action = "isDate.cfm">
<p>Enter a string, find whether it can be evaluated to a date value.
<p><input type = "Text" name = "TheTestValue" value = "<cfoutput>#Now()#
</cfoutput>">
<input type = "Submit" value = "Is it a Date?" name = "">
</form>


IsDebugMode

Description

Determines the setting of debug mode in ColdFusion Administrator.

If the debugging service is enabled and the showDebugOutput attribute value is Yes, the IsDebugMode() function returns Yes; otherwise, No.

Return value

True, if debugging mode is set in the ColdFusion Administrator; False if debugging mode is disabled.

Category

Decision functions

Syntax

IsDebugMode()

Example

<h3>IsDebugMode Example</h3>
<cfif IsDebugMode()>
 <h3>Debugging is set in the ColdFusion Administrator</h3>
<cfelse>
 <h3>Debugging is disabled</h3>
</cfif>


IsDefined

Description

Evaluates a string value to determine whether the variable named in it exists.

This function is an alternative to the ParameterExists function, which is deprecated.

Return value

True, if the variable is found, or, for a structure, if its key is defined; False, otherwise.

Returns False for an array or structure element referenced using bracket notation. For example, IsDefined("myArray[3]") always returns False, even if the array element myArray[3] has a value.

Category

Decision functions

Syntax

IsDefined("variable_name")

See also

Evaluate

History

New in ColdFusion MX: this function can process only the following constructs:

  • a simple variable
  • a named variable with dot notation
  • a named structure with dot notation (example: mystruct.key)

Parameters

Parameter | Description
variable_name | String, enclosed in quotation marks. Name of variable to test for.

Usage

When working with the URL and Form scopes, which are structures, the StructKeyExists function can sometimes be used in place of this function. The following blocks of code are equivalent:

Example

<h3>IsDefined Example</h3>

<cfif IsDefined("FORM.myString")>
<p>Because the variable FORM.myString is defined, we can show its contents.
This lets us put a FORM and its resulting action page in the same page,
while using IsDefined to control the flow of page execution.
<p>The value of "FORM.myString" is <B><I><cfoutput>#FORM.myString#
 </cfoutput></I></B>
<cfelse>
<p>During the first execution of this page, the variable "FORM.myString" is
not yet defined, so it is not evaluated.
</cfif>
...


IsK2ServerABroker

Description

Determines whether the K2Server version is K2 Broker. For more information, see GetK2ServerDocCountLimit.

This function is used primarily by the ColdFusion Verity and K2Server Administrator pages. This function uses Verity K2Server Release K2.2.0.

Return value

True, if K2Broker is in configured with ColdFusion; False, otherwise.

Category

Decision functions, Full-text search functions, Query functions

Syntax

IsK2ServerABroker()

See also

GetK2ServerDocCountLimit, IsK2ServerDocCountExceeded, IsK2ServerOnline

History

New in ColdFusion MX: This function is new.

Example

<cfoutput>IsK2ServerABroker =
$*#IsK2ServerABroker()#*$</cfoutput>


IsK2ServerDocCountExceeded

Description

Determines whether the number of documents that can be searched by the ColdFusion registered K2 Server exceed the limit. Depends on the K2Server platform limit; see GetK2ServerDocCountLimit.

This function is used primarily by the ColdFusion Verity and K2Server Administrator pages. This function uses Verity K2Server Release K2.2.0.

Return value

True, if the document count limit is exceeded; False, otherwise.

Category

Decision functions, Full-text search functions, Query functions

Syntax

IsK2ServerDocCountExceeded()

See also

GetK2ServerDocCount, GetK2ServerDocCountLimit, IsK2ServerABroker

History

New in ColdFusion 5: this function is new.

Example

<cfoutput>IsK2ServerDocCountExceeded =
$*#IsK2ServerDocCountExceeded()#*$</cfoutput>


IsK2ServerOnline

Description

Determines whether the K2Server is running and available to perform a search.

This function is used primarily by the ColdFusion Verity and K2Server Administrator pages.

This function uses Verity K2Server Release K2.2.0.

Return value

True, if the K2Server is available to perform a search; False, otherwise.

Category

Decision functions, Full-text search functions, Query functions

Syntax

IsK2ServerOnline()

See also

IsK2ServerABroker

History

New in ColdFusion MX: This function is new.

Example

<cfoutput>IsK2ServerOnline =
$*#IsK2ServerOnline()#*$</cfoutput>


IsLeapYear

Description

Determines whether a year is a leap year.

Return value

True, if year is a leap year; otherwise, False.

Category

Date and time functions, Decision functions

Syntax

IsLeapYear(year)

See also

DaysInYear

Parameters

Parameter | Description
year | Number representing a year

Example

<h3>IsLeapYear Example</h3>

<cfif IsDefined("FORM.theTestValue")>
   <cfif IsLeapYear(FORM.theTestValue)>
      <h3>The year value <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is a Leap
Year</h3>
   <cfelse>
      <h3>The year value <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is not a Leap
Year</h3>
   </cfif>
</cfif>

<form action = "isLeapYear.cfm">
<p>Enter a year value, and find out whether it is a Leap Year.
<p><input type = "Text" name = "TheTestValue" value = "
<cfoutput>#Year(Now())#</cfoutput>">
<input type = "Submit" value = "Is it a Leap Year?" name = "">
</form>


IsNumeric

Description

Determines whether a string can be converted to a numeric value. Supports numbers in U.S. number format. For other number support, use LSIsNumeric.

Return value

True, if string can be converted to a number; otherwise, False.

Category

Decision functions

Syntax

IsNumeric(string)

See also

IsBinary

Parameters

Parameter | Description
string | A string or a variable that contains one.

Example

<h3>IsNumeric Example</h3>
<cfif IsDefined("FORM.theTestValue")>
   <cfif IsNumeric(FORM.theTestValue)>
   <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput> can be
converted to a number</h3>
   <cfelse>
   <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput> cannot be
converted to a number</h3>
   </cfif>
</cfif>

<form action = "isNumeric.cfm">
<p>Enter a string, and find out whether it can be evaluated to a numeric value.

<p><input type = "Text" name = "TheTestValue" value = "123">
<input type = "Submit" value = "Is it a Number?" name = "">
</form>


IsNumericDate

Description

Evaluates the "real value" of a date/time object.

Return value

True, if number represents "real value" of a date/time object; otherwise, False.

Category

Date and time functions, Decision functions

Syntax

IsNumericDate(number)

See also

IsDate , ParseDateTime

Parameters

Parameter | Description
number | A real number

Example

<h3>IsNumericDate Example</h3>
<cfif IsDefined("FORM.theTestValue")>
<!--- test if the value is Numeric or a pre-formatted Date value --->
   <cfif IsNumeric(FORM.theTestValue) or IsDate(FORM.theTestValue)>
<!--- if this value is a numericDate value, then pass --->
      <cfif IsNumericDate(FORM.theTestValue)>
      <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is a
valid numeric date</h3>
      <cfelse>
      <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is not a
valid numeric date</h3>
      </cfif>
   <cfelse>
   <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is not a
valid numeric date</h3>
   </cfif>
</cfif>
<form action = "isNumericDate.cfm">
<p>Enter a string, and discover if it can be evaluated to a date value.
<p><input type = "Text" name = "TheTestValue" value = "<cfoutput>#Now()#
 </cfoutput>">
<input type = "Submit" value = "Is it a Date?" name = "">
</form>


IsObject

Description

Determines whether a value is an object.

Return value

True, if the value is an object whose attributes match the specified values; False, otherwise.

The basic ColdFusion types are as follows:

  • simple: integer, string, float, date, and so on
  • structure
  • array
  • user defined function

Category

Decision functions

Syntax

IsObject(value [, type [, … ]])

See also

IsDate , IsQuery

History

New in ColdFusion MX: This function is new.

Parameters

Parameter
Description
value
A value
type
String; a type name; data type of the argument.
  • any
  • array
  • binary
  • boolean
  • date
  • guid
  • numeric
  • query
  • string
  • struct
  • uuid
  • variableName
  • a component name
If the value is not a recognized type, ColdFusion processes it as a component name
component-specific parameter
See the Usage section.

Usage

This function can take other, context-specific arguments; for example, classPath, server. For a component, the parameter name is componentName.

This object returns False for query and XML objects.


IsProtected

Description

This function is obsolete. Use the newer security tools; see Authentication functions and the Application Security chapter in Developing ColdFusion MX Applications with CFML

History

New in ColdFusion MX: This function is obsolete. It does not work in ColdFusion MX and later releases.


IsQuery

Description

Determines whether value is a query.

Return value

True, if value is a query.

Category

Decision functions, Query functions

Syntax

IsQuery(value)

See also

QueryAddRow

Parameters

Parameter | Description
value | Query variable

Example

<!--- Shows an example of IsQuery and IsSimpleValue --->
<h3>IsQuery Example</h3>
<!--- define a variable called "getEmployees" --->
<CFPARAM name = "getEmployees" DEFAULT = "#Now()#">

<p>Before the query is run, the value of GetEmployees is
<cfoutput>#getEmployees#</cfoutput>

<cfif IsSimpleValue(getEmployees)>
   <p>getEmployees is currently a simple value
</cfif>
<!--- make a query on the snippets datasource --->
<cfquery name = "getEmployees" datasource = "cfsnippets">
SELECT *
FROM employees
</cfquery>

<p>After the query is run, GetEmployees contains a number of rows
that look like this (display limited to three rows):
<cfoutput QUERY = "GetEmployees" MaxRows = "3">
<pre>#Emp_ID# #FirstName# #LastName#</pre>
</cfoutput>
<cfif IsQuery(getEmployees)>
   GetEmployees is no longer a simple value, but the name of a query
</cfif>


IsSimpleValue

Description

Determines the type of a value.

Return value

True, if value is a string, number, Boolean, or date/time value; False, otherwise.

Category

Decision functions

Syntax

IsSimpleValue(value)

Parameters

Parameter | Description
value | Variable or expression

Example

<!--- Shows an example of IsQuery and IsSimpleValue --->
<h3>IsSimpleValue Example</h3>
<!--- define a variable called "getEmployees" --->
<cfparam name = "getEmployees" default = "#Now()#">

<p>Before the query is run, the value of GetEmployees is
<cfoutput>#getEmployees#</cfoutput>

<cfif IsSimpleValue(getEmployees)>
   <p>getEmployees is currently a simple value
</cfif>
<!--- make a query on the snippets datasource --->
<cfquery name = "getEmployees" datasource = "cfsnippets">
SELECT *
FROM employees
</cfquery>
<p>After the query is run, GetEmployees contains a number of rows
that look like this (display limited to three rows):
<cfoutput QUERY = "GetEmployees" MaxRows = "3">
<pre>#Emp_ID# #FirstName# #LastName#</pre>
</cfoutput>

<cfif IsQuery(getEmployees)>
   GetEmployees is no longer a simple value, but the name of a query
</cfif>


IsStruct

Description

Determines whether a variable is a structure.

Return value

True, if variable is a ColdFusion structure or is a Java object that implements the java.lang.Map interface. Returns False if the object in variable is a user-defined function (UDF).

Category

Decision functions, Structure functions

Syntax

IsStruct(variable )

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
variable | Variable name

Example

<!--- This view-only example shows the use of IsStruct. --->
<p>This file is similar to addemployee.cfm, which is called by StructNew,
StructClear, and StructDelete. It is an example of a custom tag used to
add employees. Employee information is passed through the employee
structure (the EMPINFO attribute). In UNIX, you must also add the Emp_ID.
<!---
<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif IsStruct(attributes.EMPINFO)>
   <cfoutput>Error. Invalid data.</cfoutput>
   <cfexit method = "ExitTag">
   <cfelse>
   <cfquery name = "AddEmployee" datasource = "cfsnippets">
   INSERT INTO Employees
   (FirstName, LastName, Email, Phone, Department)
   VALUES
   <cfoutput>
   (
   ‘#StructFind(attributes.EMPINFO, "firstname")#’ ,
   ‘#StructFind(attributes.EMPINFO, "lastname")#’ ,
   ‘#StructFind(attributes.EMPINFO, "email")#’ ,
   ‘#StructFind(attributes.EMPINFO, "phone")#’ ,
   ‘#StructFind(attributes.EMPINFO, "department")#’
   )
   </cfoutput>
   </cfquery>
</cfif>
<cfoutput><hr>Employee Add Complete</cfoutput>
</cfcase>
</cfswitch> --->


IsUserInRole

Description

Determines whether an authenticated user belongs to the specified Role.

Return value

True, if the authenticated user, belongs to the specified Role; False, otherwise.

Category

Authentication functions, Decision functions

Syntax

IsUserInRole("role_name")

See also

GetAuthUser

History

New in ColdFusion MX: This function is new.

Parameters

Parameter | Description
role_name | Name of a security role

Example

<cfif isUserInRole("Admin") >
   <cfoutput>Authenticated user is an administrator</cfoutput>
<cfelse isUserInRole("User") >
   <cfoutput>Authenticated user is a user</cfoutput>
</cfif>


IsWDDX

Description

Determines whether a value is a well-formed WDDX packet.

Return value

True, if the value is a well-formed WDDX packet; False, otherwise.

Category

Decision functions, XML functions

Syntax

IsWDDX(value)

History

New in ColdFusion MX: if the value parameter is not a WDDX packet, ColdFusion returns False. (In earlier releases, ColdFusion threw an error.)

Parameters

Parameter | Description
value | A WDDX packet

Usage

This function processes a WDDX packet with a validating XML parser, which uses the WDDX Document Type Definition (DTD).

To prevent CFWDDX deserialization errors, you can use this function to validate WDDX packets from unknown sources.

Example

<cfset packet="
   <wddxPacket version=’1.0’>
   <header></header>
   <data>
      <struct>
      <var name=’ARRAY’>
         <array length=’3’>
            <string>one</string>
         <string>two</string>
         </array>
      </var>
      <var name=’NUMBER’>
         <string>5</string>
      </var>
      <var name=’STRING’>
         <string>hello</string>
      </var>
      </struct>
   </data>
   </wddxPacket>"
   >
<hr>
<xmp>
<cfoutput>#packet#
</xmp>
IsWDDX() returns #iswddx(packet)#<br>
</cfoutput>


IsXmlDoc

Description

Determines whether a function parameter is an Extended Markup language (XML) document object.

Return value

True, if the function argument is an XML document object; False, otherwise.

Category

Decision functions, XML functions

Syntax

IsXmlDoc(value)

See also

IsXmlElement , IsXmlRoot , XmlChildPos , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
value | name of an XML document object


IsXmlElement

Description

Determines whether a function parameter is an Extended Markup language (XML) document object element.

Return value

True, if the function argument is an XML document object element; False, otherwise.

Category

Decision functions, XML functions

Syntax

IsXmlElement(value)

See also

IsXmlDoc , IsXmlRoot , XmlChildPos , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
value | name of an XML document object element


IsXmlRoot

Description

Determines whether a function parameter is the root element of an Extended Markup language (XML) document object.

Return value

True, if the function argument is the root object of an XML document object; False, otherwise.

Category

Decision functions, XML functions

Syntax

IsXmlRoot(value)

See also

IsXmlDoc , IsXmlElement , XmlChildPos , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
value | name of an XML document object


JavaCast

Description

Converts the data type of a ColdFusion variable to pass as an argument to an overloaded method of a Java object. Use only for scalar and string arguments.

Return value

The variable, as type type.

Category

String functions

Syntax

JavaCast(type, variable)

See also

CreateObject , cfobject

Parameters

Parameter
Description
type
Data type to which to convert variable:
  • boolean
  • int
  • long
  • double
  • string
variable
A ColdFusion variable that holds a scalar or string type

Usage

Use after creating a Java object with the cfobject tag, before calling one of its methods. If the method takes more than one overloaded argument, you must call JavaCast for each one. Use JavaCast only when a method is overloaded (because its arguments can take more than one data type, not because the method can take a variable number of arguments).

JavaCast cannot be used to cast between complex objects, nor to cast to a super-class. Use this function’s result only on calls to Java objects. Because there is not a one-to-one correspondence between internally stored ColdFusion types and Java scalar types, some conversions cannot be performed.

Example

The fooClass method fooMethod takes one overloaded argument, as follows:

public void fooMethod(String arg);
public void fooMethod(int arg);

Within ColdFusion, you use the following code:

<cfobject
   type = java
   CLASS = fooClass name = obj>
   <!--- ColdFusion may treat this as a string or a real number --->
   <cfset x = 33>
   <!--- Perform an explicit cast to an int. --->
   <cfset myInt = JavaCast("int", x)>
   <cfset void = fooMethod(myInt)>
   <!--- Perform an explicit cast to a string. --->
   <cfset myString = javaCast("String", x)>
   <cfset void = fooMethod(myString)>
</cfobject>


JSStringFormat

Description

Escapes special JavaScript characters, such as single quotation mark, double quotation mark, and newline.

Return value

A string that is safe to use with JavaScript.

Category

String functions

Syntax

JSStringFormat(string)

Parameters

Parameter | Description
string | A string or a variable that contains one.

Usage

Escapes special JavaScript characters, so you can put arbitrary strings safely into JavaScript.

Example

<!--- This example shows the use of the JSStringFormat function. ---->
<h3>JSStringFormat</h3>
<cfset stringValue = "An example string value with a tab chr(8),
a newline (chr10) and some ""quoted"" 'text'">

<p>This is the string we have created:<br>
<cfoutput>#stringValue#</cfoutput>
</p>
<cfset jsStringValue = JSStringFormat(#stringValue#)>
<!----- Generate an alert from the JavaScript string jsStringValue. ---->
<SCRIPT>
s = "<cfoutput>#jsStringValue#</cfoutput>";
alert(s);
</SCRIPT>

Previous


ColdFusion Functions: Lcase--YesNoFormat


LCase

Description

Converts the alphabetic characters in a string to lowercase.

Return value

A string, converted to lowercase.

Category

String functions

Syntax

LCase(string)

See also

UCase

Parameters

Parameter | Description
string | A string or a variable that contains one

Example

<h3>LCase Example</h3>

<cfif IsDefined("FORM.sampleText")>
   <cfif FORM.sampleText is not "">
   <p>Your text, <cfoutput>#FORM.sampleText#</cfoutput>,
   returned in lowercase is <cfoutput>#LCase(FORM.sampleText)#
   </cfoutput>.
   <cfelse>
   <p>Please enter some text.
   </cfif>
</cfif>

<form action = "lcase.cfm">
<p>Enter your text. Press "submit" to see it returned in lowercase:

<p><input type = "Text" name = "SampleText" value = "SAMPLE">
<input type = "Submit" name = "" value = "submit">
</form>
Next


Left

Description

Determines the number of characters from the beginning of the string parameter to the location specified by the count parameter.

Return value

Number; count of characters.

Category

String functions

Syntax

Left(string, count)

See also

Right , Mid , Len

Parameters

Parameter | Description
string | A string or a variable that contains one.
count | A positive integer or a variable that contains one. Number of characters to return.

Example

<h3>Left Example</h3>

<cfif IsDefined("Form.MyText")>
<!--- if len is 0, then err --->
   <cfif Len(FORM.myText) is not 0>
      <cfif Len(FORM.myText) LTE FORM.RemoveChars>
      <p>Your string <cfoutput>#FORM.myText#</cfoutput>
      only has <cfoutput>#Len(FORM.myText)#</cfoutput>
      characters. You cannot output the <cfoutput>#FORM.removeChars#
       </cfoutput>
      leftmost characters of this string because it is not long enough.
      <cfelse>
      <p>Your original string: <cfoutput>#FORM.myText#</cfoutput>
      <p>Your changed string, showing only the
       <cfoutput>#FORM.removeChars#</cfoutput> leftmost characters:
      <cfoutput>#Left(Form.myText, FORM.removeChars)#
      </cfoutput>
      </cfif>
   <cfelse>
   <p>Please enter a string
   </cfif>
</cfif>


Len

Description

Determines the length of a string or binary object.

Return value

Number; length of a string or a binary object.

Category

String functions

Syntax

Len(string or binary object)

See also

ToBinary , Left , Right , Mid

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode character values 0–65535. (ColdFusion 5 and earlier releases supported ASCII values 1–255. When calculating a length, some string-processing functions processed the ASCII 0 (NUL) character, but did not process subsequent characters of the string.)

Parameters

Parameter | Description
string | A string, the name of a string, or a binary object

Example

<h3>Len Example</h3>

<cfif IsDefined("Form.MyText")>
<!--- if len is 0, then err --->
   <cfif Len(FORM.myText) is not 0>
   <p>Your string, <cfoutput>"#FORM.myText#"</cfoutput>,
   has <cfoutput>#Len(FORM.myText)#</cfoutput> characters.
   <cfelse>
   <p>Please enter a string of more than 0 characters.
   </cfif>
</cfif>

<form action = "len.cfm">
<p>Type in some text to see the length of your string.

<br><input type = "Text" name = "MyText">
<br><input type = "Submit" name = "Remove characters">
</form>


ListAppend

Description

Concatenates a list or element to a list.

Return value

A copy of the list, with value appended. If delimiter = "", returns a copy of the list, unchanged.

Category

List functions

Syntax

ListAppend(list, value [, delimiters ])

See also

ListPrepend , ListInsertAt , ListGetAt , ListLast , ListSetAt

Parameters

Parameter | Description
list | A list or a variable that contains one.
value | An element or a list of elements.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion uses only the first character.

Usage

ColdFusion inserts a delimiter character before value.

To add an element to the beginning or end of a list, Macromedia recommends that you do so with code such as the following, rather than with the listAppend or listPrepend functions:

<cfset MyValue = "another element">
<cfif listLen(myList) is 0>
   <cfset myList = MyValue>
<cfelse>
   <cfset myList = myList & ", " & MyValue>
</cfif>

The following table shows examples of ListAppend processing:

Statement
Output
Comment
listAppend('elem1,elem2', '' )

elem1,elem2,
Appended element is empty; delimiter is last character in list; list length is 2
listAppend('', 'elem1,elem2' )

elem1,elem2
List length is 2
listAppend
("one___two", "three", "___")

"one___two_three"
Inserted the first character of delimiters before "three."

Example

<h3>ListAppend Example</h3>
<!--- First, query to get some values for our list elements--->
<cfquery name = "GetParkInfo" datasource = "cfsnippets">
SELECT PARKNAME,CITY,STATE
FROM PARKS WHERE PARKNAME LIKE ‘AL%’
</cfquery>
<cfset temp = ValueList(GetParkInfo.ParkName)>
<cfoutput>
<p>The original list: #temp#
</cfoutput>
<!--- now, append a park name to the list --->
<cfset temp2 = ListAppend(Temp, "ANOTHER PARK")>
...


ListChangeDelims

Description

Changes a list delimiter.

Return value

A copy of the list, with each delimiter character replaced by new_delimiter.

Category

List functions

Syntax

ListChangeDelims(list, new_delimiter [, delimiters ])

See also

ListFirst , ListQualify

Parameters

Parameter | Description
list | A list or a variable that contains one.
new_delimiter | Delimiter string or a variable that contains one. Can be an empty string. ColdFusion processes the string as one delimiter.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Example

<h3>ListChangeDelims Example</h3>
<p>ListChangeDelims lets you change the delimiters of a list.
<!--- First, query to get some values for our list elements--->
<CFQUERY NAME="GetParkInfo" DATASOURCE="cfsnippets">
SELECT    PARKNAME,CITY,STATE
FROM    Parks
WHERE    PARKNAME LIKE 'BA%'
</CFQUERY>
<CFSET temp = ValueList(GetParkInfo.ParkName)>
<cfoutput>
<p>The original list: <p>#temp#
</cfoutput>
<!--- Change the delimiters in the list --->
<CFSET temp2 = ListChangeDelims(Temp, "|:P|", ",")>
<cfoutput>
<p>After executing the statement
<strong>ListChangeDelims(Temp, "|:P|", ",")</strong>,
the updated list: <p>#temp2#
</cfoutput>


ListContains

Description

Determines the index of the first list element that contains a specified substring.

Return value

Index of the first list element that contains substring. If not found, returns zero.

Category

List functions

Syntax

ListContains(list, substring [, delimiters ])

See also

ListContainsNoCase , ListFind

Parameters

Parameter | Description
list | A list or a variable that contains one.
substring | A string or a variable that contains one. The search is case-sensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<!--- This example shows differences between ListContains and ListFind --->
<!--- Create a list composed of the elements one, two, three. ---->
<cfset aList = "one">
<cfset aList = ListAppend(aList, "two")>
<cfset aList = ListAppend(aList, "three")>
<p>Here is a list: <cfoutput>#aList#</cfoutput>
<p><strong>ListContains</strong> checks for substring "wo" in the list elements:
<cfoutput>
   <p>&nbsp;&nbsp;&nbsp;Substring "wo" is in
<B>element #ListContains(aList, "wo")#</B> of list.
</cfoutput>
<p>ListFind cannot check for a substring within an element; therefore, in the
   code, it does not find substring "wo" (it returns 0):
<cfoutput>
   <p>&nbsp;&nbsp;&nbsp;Substring "wo" is in <b>element #ListFind(aList, "wo")#
   </b> of the list.</cfoutput>
<p><p>If you specify a string that exactly equals an entire list element, such
   as "two", both ListContains and ListFind find it, in the second element:
   <p>&nbsp;&nbsp;&nbsp;<strong>ListContains</strong>:
<cfoutput>
The string "two" is in <b>element #ListContains(aList, "two")#</b> of the list.
</cfoutput>
&nbsp;&nbsp;&nbsp;<p><strong>ListFind</strong>:
<cfoutput>
The string "two" is in <b>element #ListFind(aList, "two")#</b> of the list.
</cfoutput>


ListContainsNoCase

Description

Determines the index of the first list element that contains a specified substring.

Return value

Index of the first list element that contains substring, regardless of case. If not found, returns zero.

Category

List functions

Syntax

ListContainsNoCase(list, substring [, delimiters ])

See also

ListContains , ListFindNoCase

Parameters

Parameter | Description
list | A list or a variable that contains one.
substring | A string or a variable that contains one. The search is case-insensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListContainsNoCase Example</h3>

<cfif IsDefined("FORM.letter")>
   <!--- First, query to get some values for our list elements--->
   <cfquery name = "GetParkInfo" datasource = "cfsnippets">
   SELECT PARKNAME,CITY,STATE
   FROM PARKS
   WHERE PARKNAME LIKE ‘#FORM.letter#%’
   </cfquery>
   <cfset tempList = ValueList(GetParkInfo.City)>
   <cfif ListContainsNoCase(tempList, FORM.yourCity) is not 0 OR
    FORM.yourCity is "">
   <p><cfif FORM.yourCity is "">The list of parks for the letter
    <cfoutput>#FORM.Letter#</cfoutput>


ListDeleteAt

Description

Deletes an element from a list.

Return value

A copy of the list, without the specified element.

Category

List functions

Syntax

ListDeleteAt(list, position [, delimiters ])

See also

ListGetAt , ListSetAt , ListLen

Parameters

Parameter | Description
list | A list or a variable that contains one.
position | A positive integer or a variable that contains one. Position at which to delete element. The first list position is 1.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

To use this and other functions with the default delimiter (comma), you can code as follows:

<cfset temp2 = ListDeleteAt(temp, "3")>

To specify another delimiter, you code as follows:

<cfset temp2 = ListDeleteAt(temp, "3", ";")>

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<!--- First, query to get some values for our list elements--->
<CFQUERY NAME="GetParkInfo" DATASOURCE="cfsnippets">
   SELECT    PARKNAME,CITY,STATE
   FROM Parks
   WHERE    PARKNAME LIKE 'CHI%'
</CFQUERY>
<CFSET temp = ValueList(GetParkInfo.ParkName)>
<CFSET deleted_element = ListGetAt(temp, "3", ",")>
<cfoutput>
<p>The original list: #temp#
</cfoutput>
<!--- Delete the third element from the list --->
<CFSET temp2 = ListDeleteAt(Temp, "3")>
<cfoutput>
<p>The changed list: #temp2#
<p><I>This list element:<br>#deleted_element#<br> is no longer present
at position three of the list.</I> </cfoutput>


ListFind

Description

Determines the index of the first list element in which a specified value occurs. Case-sensitive.

Return value

Index of the first list element that contains value, with matching case. If not found, returns zero. The search is case-sensitive.

Category

List functions

Syntax

ListFind(list, value [, delimiters ])

See also

ListContains , ListFindNoCase

Parameters

Parameter | Description
list | A list or a variable that contains one
value | A string, a number, or a variable that contains one. Item for which to search. The search is case-sensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<!--- Uses ListFind and ListFindNoCase to see if a substring exists in a list --->
<form action="./listfind.cfm" method="POST">
   <p>Try changing the case in Leary's last name:
   <br><input type="Text" size="25" name="myString" value="Leary">
   <p>Pick a search type:
      <select name="type">
         <option value="ListFind" selected>Case-Sensitive
         <option value="ListFindNoCase">Case-Insensitive
      </select>
   <input type="Submit" name="" value="Search Employee List">
</form>

<!--- wait to have a string for searching defined --->
<cfif IsDefined("form.myString") and IsDefined("form.type")>

<cfquery name="SearchEmpLastName" datasource="cfsnippets">
   SELECT  FirstName, RTrim(LastName) AS LName, Phone, Department
   FROM    Employees
</cfquery>

<cfset myList = ValueList(SearchEmpLastName.LName)>
<!--- Is this case-sensitive or case-insensitive searching --->
<cfif form.type is "ListFind">
   <cfset temp = ListFind(myList, form.myString)>
      <cfif temp is 0>
         <h3>An employee with that exact last name was not found</h3>
      <cfelse>
         <cfoutput>
         <p>Employee #ListGetAt(ValueList(SearchEmpLastName.FirstName), temp)#
         #ListGetAt(ValueList(SearchEmpLastName.LName), temp)#, of the
         #ListGetAt(ValueList(SearchEmpLastName.Department), temp)# Department,
         can be reached at #ListGetAt(ValueList(SearchEmpLastName.Phone), temp)#.
         <p>This was the first employee found under this case-sensitive last name
         search.
         </cfoutput>
      </cfif>
      <cfelse>
         <cfset temp = ListFindNoCase(myList, form.myString)>
         <cfif temp is 0>
            <h3>An employee with that exact last name was not found</h3>
         <cfelse>
            <cfoutput>
            <p>Employee #ListGetAt(ValueList(SearchEmpLastName.FirstName), temp)#
            #ListGetAt(ValueList(SearchEmpLastName.LName), temp)#, of the
            #ListGetAt(ValueList(SearchEmpLastName.Department), temp)# Department,
            can be reached at #ListGetAt(ValueList(SearchEmpLastName.Phone), temp)#.
            <p>This was the first employee found under this case-insensitive last
            name search.
         </cfoutput>
      </cfif>
   </cfif>
</cfif>


ListFindNoCase

Description

Determines the index of the first list element in which a specified value occurs.

Return value

Index of the first list element that contains value. If not found, returns zero. The search is case-insensitive.

Category

List functions

Syntax

ListFindNoCase(list, value [, delimiters ])

See also

ListContains, ListFind

Parameters

Parameter | Description
list | A list or a variable that contains one.
value | Number or string for which to search. The search is case-insensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<!--- Uses ListFind and ListFindNoCase to see if a substring exists in a list --->
<form action="./listfind.cfm" method="POST">
   <p>Try changing the case in Leary's last name:
   <br><input type="Text" size="25" name="myString" value="Leary">
   <p>Pick a search type:
      <select name="type">
         <option value="ListFind" selected>Case-Sensitive
         <option value="ListFindNoCase">Case-Insensitive
      </select>
   <input type="Submit" name="" value="Search Employee List">
</form>

<!--- wait to have a string for searching defined --->
<cfif IsDefined("form.myString") and IsDefined("form.type")>

<cfquery name="SearchEmpLastName" datasource="cfsnippets">
   SELECT  FirstName, RTrim(LastName) AS LName, Phone, Department
   FROM    Employees
</cfquery>

<cfset myList = ValueList(SearchEmpLastName.LName)>
<!--- Is this case-sensitive or case-insensitive searching --->
<cfif form.type is "ListFind">
   <cfset temp = ListFind(myList, form.myString)>
      <cfif temp is 0>
         <h3>An employee with that exact last name was not found</h3>
      <cfelse>
         <cfoutput>
         <p>Employee #ListGetAt(ValueList(SearchEmpLastName.FirstName), temp)#
         #ListGetAt(ValueList(SearchEmpLastName.LName), temp)#, of the
         #ListGetAt(ValueList(SearchEmpLastName.Department), temp)# Department,
         can be reached at #ListGetAt(ValueList(SearchEmpLastName.Phone), temp)#.
         <p>This was the first employee found under this case-sensitive last name
         search.
         </cfoutput>
      </cfif>
      <cfelse>
         <cfset temp = ListFindNoCase(myList, form.myString)>
         <cfif temp is 0>
            <h3>An employee with that exact last name was not found</h3>
         <cfelse>
            <cfoutput>
            <p>Employee #ListGetAt(ValueList(SearchEmpLastName.FirstName), temp)#
            #ListGetAt(ValueList(SearchEmpLastName.LName), temp)#, of the
            #ListGetAt(ValueList(SearchEmpLastName.Department), temp)# Department,
            can be reached at #ListGetAt(ValueList(SearchEmpLastName.Phone), temp)#.
            <p>This was the first employee found under this case-insensitive last
            name search.
         </cfoutput>
      </cfif>
   </cfif>
</cfif>


ListFirst

Description

Gets the first element of a list.

Return value

The first element of a list. If the list is empty, returns an empty string.

Category

List functions

Syntax

ListFirst(list [, delimiters ])

See also

ListGetAt , ListLast , ListQualify

Parameters

Parameter | Description
list | A list or a variable that contains one.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListFirst Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
   SELECT Username, Subject, Posted
   FROM  Messages
</cfquery>

<cfset temp = ValueList(GetMessageUser.Username)>
<p>Before editing the list, it is:&nbsp;
<cfoutput>#ValueList(GetMessageUser.Username)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<!--- Show the first user in the list --->
<p>The first user in the list is:
<cfoutput>#ListFirst(temp)#</cfoutput>
<p>The rest of the list is:&nbsp;<cfoutput>#ListRest(temp)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<p>The last user in the list is: <cfoutput>#ListLast(temp)#</cfoutput>


ListGetAt

Description

Gets a list element at a specified position.

Return value

Index of the list element at position position.

Category

List functions

Syntax

ListGetAt(list, position [, delimiters ])

See also

ListFirst , ListLast , ListQualify , ListSetAt

Parameters

Parameter | Description
list | A list or a variable that contains one.
position | A positive integer or a variable that contains one. Position at which to get element. The first list position is 1.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

If you use list functions on strings that are delimited by a delimiter character and a space, a returned list element might contain a leading space; you use the trim function to remove such spaces from a returned element. For example, consider this list:

<cfset myList = "one hundred, two hundred, three hundred">

To get a value from this list, use the trim function to remove the space before the returned value:

<cfset MyValue = #trim(listGetAt(myList, 2))#>

With this usage, MyValue = "two hundred", not " two hundred", and spaces within a list element are preserved.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListGetAt Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
   SELECT Username, Subject, Posted
   FROM  Messages
</cfquery>
<cfset temp = ValueList(GetMessageUser.Username)>
<!--- loop through the list and show it with ListGetAt --->
<h3>This list of usernames who have posted messages numbers
<cfoutput>#ListLen(temp)#</cfoutput> users.</h3>
<ul>
<cfloop From = "1" To = "#ListLen(temp)#" index = "Counter">
   <cfoutput><li>Username #Counter#: #ListGetAt(temp, Counter)# </cfoutput>
</cfloop>
</ul>


ListInsertAt

Description

Inserts an element in a list.

Return value

A copy of the list, with value inserted at the specified position.

Category

List functions

Syntax

ListInsertAt(list, position, value [, delimiters ])

See also

ListDeleteAt , ListAppend , ListPrepend , ListSetAt

Parameters

Parameter | Description
list | A list or a variable that contains one.
position | A positive integer or a variable that contains one. Position at which to insert element. The first list position is 1.
value | An element or a list of elements.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

When inserting an element, ColdFusion inserts a delimiter. If delimiters contains more than one delimiter, ColdFusion uses the first delimiter in the string; if delimiters is omitted, ColdFusion uses a comma.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<!--- This example shows ListInsertAt --->
<cfquery name = "GetParkInfo" datasource = "cfsnippets">
SELECT PARKNAME,CITY,STATE
FROM PARKS
WHERE PARKNAME LIKE ‘DE%’
</cfquery>
<cfset temp = ValueList(GetParkInfo.ParkName)>
<cfset insert_at_this_element = ListGetAt(temp, "3", ",")>
<cfoutput>
<p>The original list: #temp#
</cfoutput>
<cfset temp2 = ListInsertAt(Temp, "3", "my Inserted Value")>


ListLast

Description

Gets the last element of a list.

Return value

The last element of the list.

Category

List functions

Syntax

ListLast(list [, delimiters ])

See also

ListGetAt , ListFirst

Parameters

Parameter | Description
list | A list or a variable that contains one.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

If you use list functions on strings that are delimited by a delimiter character and a space, a returned list element might contain a leading space; you use the trim function to remove such spaces from a returned element. For example, consider this list:

<cfset myList = "one hundred, two hundred, three hundred">

To get a value from this list, use the trim function to remove the space before the returned value:

<cfset MyValue = #trim(listGetAt(myList, 2))#>

With this usage, MyValue = "two hundred", not " two hundred", and spaces within a list element are preserved.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListFirst, ListLast, and ListRest Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
   SELECT Username, Subject, Posted
   FROM  Messages
</cfquery>
<cfset temp = ValueList(GetMessageUser.Username)>
<p>Before editing the list, it is:&nbsp;
<cfoutput>#ValueList(GetMessageUser.Username)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<!--- Show the first user in the list --->
<p>The first user in the list is: <cfoutput>#ListFirst(temp)#</cfoutput>
<p>The rest of the list is:&nbsp;<cfoutput>#ListRest(temp)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<p>The last user in the list is: <cfoutput>#ListLast(temp)#</cfoutput>


ListLen

Description

Determines the number of elements in a list.

Integer; the number of elements in a list.

Category

List functions

Syntax

ListLen(list [, delimiters ])

See also

ListAppend , ListDeleteAt , ListInsertAt , ListPrepend

Parameters

Parameter | Description
list | A list or a variable that contains one.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Here are some examples of ListLen processing:

Statement
Output
Comment
ListLen('a,b, c,,,d')

4
Third element is " c"
ListLen('a,b, c,,,d',',')

4
Fourth element is "d'"
ListLen('elem_1___elem_2___elem_3')

1

ListLen('elem*1***elem*2***elem*3')

1

ListLen('elem_1___elem_2___elem_3','_')

6

Example

<h3>ListLen Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
   SELECT Username, Subject, Posted
   FROM  Messages
</cfquery>
<cfset temp = ValueList(GetMessageUser.Username)>
<!--- loop through the list and show it with ListGetAt --->
<h3>This is a list of usernames who have posted messages
<cfoutput>#ListLen(temp)#</cfoutput> users.</h3>
<ul>
<cfloop From = "1" TO = "#ListLen(temp)#" INDEX = "Counter">
   <cfoutput><li>Username #Counter#:
    #ListGetAt(temp, Counter)#</cfoutput>
</cfloop>
</ul>


ListPrepend

Description

Inserts an element at the beginning of a list.

Return value

A copy of the list, with value inserted at the first position.

Category

List functions

Syntax

ListPrepend(list, value [, delimiters ])

See also

ListAppend , ListInsertAt , ListSetAt

Parameters

Parameter | Description
list | A list or a variable that contains one.
value | An element or a list of elements.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

When prepending an element to a list, ColdFusion inserts a delimiter. If delimiters contains more than one delimiter character, ColdFusion uses the first delimiter in the string; if delimiters is omitted, ColdFusion uses a comma.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

If the delimiters parameter is empty (""), ColdFusion replaces the list with the contents of value.

To add an element to the beginning or end of a list, Macromedia recommends that you do so with code such as the following, rather than with the listAppend or listPrepend functions:

<cfset MyValue = "another element">
<cfif listLen(myList) is 0>
   <cfset myList = MyValue>
<cfelse>
   <cfset myList = myList & ", " & MyValue>
</cfif>

Example

<!--- This example shows ListPrepend --->
<cfquery name = "GetParkInfo" datasource = "cfsnippets">
   SELECT PARKNAME,CITY,STATE
   FROM PARKS
   WHERE PARKNAME LIKE ‘DE%’
</cfquery>
<cfset temp = ValueList(GetParkInfo.ParkName)>
<cfset first_element = ListFirst(temp)>
<cfoutput><p>The original list: #temp#</cfoutput>
<!--- now, insert an element at position 1--->
<cfset temp2 = ListPrepend(Temp, "my Inserted Value")>


ListQualify

Description

Inserts a string at the beginning and end of list elements.

Return value

A copy of the list, with qualifier before and after the specified element(s).

Category

List functions

Syntax

ListQualify(list, qualifier [, delimiters ] [, elements ])

History

New in ColdFusion MX: As the elements parameter value, you must specify "all" or "char"; otherwise, ColdFusion throws an exception. (In earlier releases, the function ignored an invalid value, and used "all"; this was inconsistent with other functions.)

Parameters

Parameter
Description
list
A list or a variable that contains one.
qualifier
A string or a variable that contains one. Character or string to insert before and after the list elements specified in the elements attribute.
delimiters
A string or a variable that contains one. Character(s) that separate list elements. Default: comma.
If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.
elements
  • all: all elements
  • char: elements that are composed of alphabetic characters

Usage

The new list might not preserve all of the delimiters in the list.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<cfquery name = "GetEmployeeNames" datasource = "cfsnippets">
SELECT    FirstName, LastName
FROM    Employees
</cfquery>

<h3>ListQualify Example</h3>
<p>This example uses ListQualify to put the full names of the
employees in the query within quotation marks.</p>
<cfset myArray = ArrayNew(1)>

<!--- loop through query; append these names successively to the last element --->
<cfloop query = "GetEmployeeNames">
   <cfset temp = ArrayAppend(myArray, "#FirstName# #LastName#")>
</cfloop>

<!--- sort that array descending alphabetically --->
<cfset myAlphaArray = ArraySort(myArray, "textnocase")>

<!--- show the resulting array as a list --->
<cfset myList = ArrayToList(myArray, ",")>

<cfoutput>
   <p>The contents of the unqualified list are as follows:   </p>
   #myList#
</cfoutput>

<!--- show the resulting alphabetized array as a qualified list with
single quotes around each full name.    --->
<cfset qualifiedList1 = ListQualify(myList,"'",",","CHAR")>

<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the qualified list are as follows:   </p>
   <p>#qualifiedList1#</p>
</cfoutput>

<!--- show the resulting alphabetized array as a qualified list with quotation
marks around each full name. We use &quot; to denote quotation marks
because the quotation mark character is a control character. --->
<cfset qualifiedList2 = ListQualify(myList,"&quot;",",","CHAR")>

<!--- output the array as a list --->
<cfoutput>
   <p>The contents of the second qualified list are:   </p>
   <p>#qualifiedList2#</p>
</cfoutput>


ListRest

Description

Gets a list, without its first element.

Return value

A copy of list, without the first element. If list has one element, returns an empty list.

Category

List functions

Syntax

ListRest(list [, delimiters ])

See also

ListFirst , ListGetAt , ListLast

Parameters

Parameter | Description
list | A list or a variable that contains one.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

If the list begins with one or more empty entries, this function drops them, as well as the first element.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListFirst, ListLast, and ListRest Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
   SELECT Username, Subject, Posted
   FROM  Messages
</cfquery>

<cfset temp = ValueList(GetMessageUser.Username)>
<p>Before editing the list, it is:&nbsp;
<cfoutput>#ValueList(GetMessageUser.Username)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<p>The first user in the list is:
<cfoutput>#ListFirst(temp)# </cfoutput>
<p>The rest of the list is:&nbsp;<cfoutput>#ListRest(temp)#</cfoutput>.
<p>(Users who posted more than once are listed more than once.)
<p>The last user in the list is: <cfoutput>#ListLast(temp)#</cfoutput>


ListSetAt

Description

Assigns a value to a list element.

Return value

A copy of a list, with a value assigned to the element at a specified position.

Category

List functions

Syntax

ListSetAt(list, position, value [, delimiters ])

See also

ListDeleteAt , ListGetAt , ListInsertAt

History

New in ColdFusion MX: ColdFusion MX does not modify delimiters in the list. (In earlier releases, in some cases, replaced delimiters with the first character in the delimiters parameter.)

Parameters

Parameter | Description
list | A list or a variable that contains one.
position | A positive integer or a variable that contains one. Position at which to set a value. The first list position is 1.
value | An element or a list of elements.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

When assigning an element to a list, ColdFusion inserts a delimiter. If delimiters contains more than one delimiter, ColdFusion uses the first delimiter in the string, or, if delimiters was omitted, a comma.

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListSetAt Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
SELECT Username, Subject, Posted
FROM  Messages
</cfquery>

<cfset temp = ValueList(GetMessageUser.Subject)>

<!--- loop through the list and show it with ListGetAt --->
<h3>This is a list of <cfoutput>#ListLen(temp)#</cfoutput>
subjects posted in messages.</h3>

<cfset ChangedElement = ListGetAt(temp, 2)>
<cfset TempToo = ListSetAt(temp, 2, "I changed this subject", ",")>
<ul>
<cfloop From = "1" To = "#ListLen(temptoo)#" INDEX = "Counter">
   <cfoutput><li>(#Counter#) SUBJECT: #ListGetAt(temptoo, Counter)#
   </cfoutput>
</cfloop>
</ul>
<p>Note that element 2, "<cfoutput>#changedElement#</cfoutput>",
has been altered to "I changed this subject" using ListSetAt.


ListSort

Description

Sorts list elements according to a sort type and sort order.

Return value

A copy of a list, sorted.

Category

List functions

Syntax

ListSort(list, sort_type [, sort_order] [, delimiters ])

History

New in ColdFusion MX: in a textnocase, descending sort, this function might return elements in a different sort order than in earlier releases. If sort_type = "textnocase" and sort_order = "desc", ColdFusion MX processes elements that differ only in case differently from earlier releases. ColdFusion MX outputs the elements in the reverse of the ascending order. Earlier releases do not change order of elements that differ only in case. Both operations are correct. The new operation ensures that an ascending and descending sort output elements in exactly reverse order.

For example, in a textnocase, desc sort of d,a,a,b,A, the following occurs:

  • ColdFusion MX returns d,b,A,a,a
  • Earlier ColdFusion releases return d,b,a,a,A

(In a textnocase, asc sort, all ColdFusion releases return a,a,A,b,d.)

Parameters

Parameter
Description
list
A list or a variable that contains one.
sort_type
  • numeric: sorts numbers
  • text: sorts text alphabetically, taking case into account (also known as case sensitive). All letters of one case precede the first letter of the other case:
    • - aabzABZ, if sort_order = "asc" (ascending sort)
    - ZBAzbaa, if sort_order = "desc" (descending sort)
  • textnocase: sorts text alphabetically, without regard to case (also known as case-insensitive). A letter in varying cases precedes the next letter:
    • - aAaBbBzzZ, in an ascending sort; preserves original intra-letter order
    - ZzzBbBaAa, in a descending sort; reverses original intra-letter order
sort_order
  • asc - ascending sort order. Default.
    • - aabzABZ or aAaBbBzzZ, depending on value of sort_type, for letters
    - from smaller to larger, for numbers
  • desc - descending sort order.
    • - ZBAzbaa or ZzzBbBaAa, depending on value of sort_type, for letters
    - from larger to smaller, for numbers
delimiters
A string or a variable that contains one. Character(s) that separate list elements. Default: comma.
If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListSort Example</h3>

<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
SELECT       Username, Subject, Posted
FROM       Messages
</cfquery>

<cfset myList = ValueList(GetMessageUser.UserName)>
<p>Here is the unsorted list. </p>
<cfoutput>#myList#
   </cfoutput>
<p>Here is the list sorted alphabetically:</p>
<cfset sortedList = ListSort(myList, "Text")>
<cfoutput>#sortedList#
   </cfoutput>

<p>Here is a numeric list that is to be sorted in descending order.</p>
<cfset sortedNums = ListSort("12,23,107,19,1,65","Numeric", "Desc")>
<cfoutput>#sortedNums# </cfoutput>

<p>Here is a list that must be sorted numerically, since it contains
negative and positive numbers, and decimal numbers. </p>
<cfset sortedNums2 = ListSort("23.75;-34,471:100,-9745","Numeric", "ASC", ";,:")>
<cfoutput>#sortedNums2# </cfoutput>

<p>Here is a list to be sorted alphabetically without consideration of case.</p>
<cfset sortedMix =
   ListSort("hello;123,HELLO:jeans,-345,887;ColdFusion:coldfusion",
      "TextNoCase", "ASC", ";,:")>
<cfoutput>#sortedMix# </cfoutput>


ListToArray

Description

Copies the elements of a list to an array.

Return value

An array

Category

Array functions, Conversion functions, List functions

Syntax

ListToArray(list [, delimiters ])

See also

ArrayToList

Parameters

Parameter | Description
list | A list or a variable that contains one. You define a list variable with a cfset statement.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Usage

ColdFusion ignores empty list elements; thus, the list "a,b,c,,,d" has four elements.

Example

<h3>ListToArray Example</h3>
<!--- Find a list of users who wrote messages --->
<cfquery name = "GetMessageUser" datasource = "cfsnippets">
SELECT Username, Subject, Posted
FROM  Messages
</cfquery>
<cfset myList = ValueList(GetMessageUser.UserName)>
<p>My list is a list with <cfoutput>#ListLen(myList)#</cfoutput>
 elements.
<cfset myArrayList = ListToArray(myList)>
<p>My array list is an array with <cfoutput>#ArrayLen(myArrayList)#
 </cfoutput> elements.


ListValueCount

Description

Counts instances of a specified value in a list. The search is case-sensitive.

Return value

The number of instances of value in the list.

Category

List functions, String functions

Syntax

ListValueCount(list, value [, delimiters ])

See also

ListValueCountNoCase

Parameters

Parameter | Description
list | A list or a variable that contains one.
value | String or number or a variable that contains one. Item for which to search. The search is case-sensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Example

<cfquery name = "SearchByDepartment" datasource = "cfsnippets">
SELECT    Department
FROM    Employees
</cfquery>
<h3>ListValueCount Example</h3>
<p>This example uses ListValueCount to count employees in a department.

<form action = "listvaluecount.cfm">
<p>Select a department:</p>
   <select name = "departmentName">
         <option value = "Accounting">
            Accounting
         </OPTION>
         <option value = "Administration">
            Administration
         </OPTION>
         <option value = "Engineering">
            Engineering
         </OPTION>
         <option value = "Sales">
            Sales
         </OPTION>
   </select>
<input type = "Submit" name = "Submit" value = "Search Employee List">
</form>

<!--- wait to have a string for searching defined --->
<cfif IsDefined("FORM.Submit") and IsDefined("FORM.departmentName")>
   <cfset myList = ValueList(SearchByDepartment.Department)>
   <cfset numberInDepartment = ListValueCount(myList, FORM.departmentName)>

   <cfif numberInDepartment is 0>
      <h3>There are no employees in <cfoutput>#FORM.departmentName#</cfoutput></h3>
   <cfelseIf numberInDepartment is 1>
      <cfoutput>      <p>There is only one person in #FORM.departmentName#.
      </cfoutput>
   <cfelse>
      <cfoutput>      <p>There are #numberInDepartment# people in #FORM.departmentName#.
      </cfoutput>
   </cfif>
</cfif>


ListValueCountNoCase

Description

Counts instances of a specified value in a list. The search is case-insensitive.

Return value

The number of instances of value in the list.

Category

List functions

Syntax

ListValueCountNoCase(list, value [, delimiters ])

See also

ListValueCount

Parameters

Parameter | Description
list | A list or a variable that contains one.
value | String or number or a variable that contains one. Item for which to search. The search is case-insensitive.
delimiters | A string or a variable that contains one. Character(s) that separate list elements. Default: comma. If this parameter contains more than one character, ColdFusion processes each occurrence of each character as a delimiter.

Example

<cfquery name = "SearchByDepartment" datasource = "cfsnippets">
SELECT    Department
FROM    Employees
</cfquery>

<h3>ListValueCountNoCase Example</h3>
<p>This example uses ListValueCountNoCase to count employees in a department.

<form action = "listvaluecountnocase.cfm">
<p>Select a department:</p>
   <select name = "departmentName">
         <option value = "Accounting">
            Accounting
         </OPTION>
         <option value = "Administration">
            Administration
         </OPTION>
         <option value = "Engineering">
            Engineering
         </OPTION>
         <option value = "Sales">
            Sales
         </OPTION>
   </select>
   </select>
<input type = "Submit" name = "Submit" value = "Search Employee List">
</form>
<!--- wait to have a string for searching defined --->
<cfif IsDefined("FORM.Submit") and IsDefined("FORM.departmentName")>
   <cfset myList = ValueList(SearchByDepartment.Department)>
   <cfset numberInDepartment = ListValueCountNoCase(myList,
      FORM.departmentName)>

   <cfif numberInDepartment is 0>
      <h3>There are no employees in <cfoutput>#FORM.departmentName#      </cfoutput></h3>
   <cfelseIf numberInDepartment is 1>
      <cfoutput>      <p>There is only one person in #FORM.departmentName#.
      </cfoutput>
   <cfelse>
      <cfoutput>      <p>There are #numberInDepartment# people in #FORM.departmentName#.
      </cfoutput>
   </cfif>
</cfif>


LJustify

Description

Left justifies characters in a string of a specified length.

Return value

A copy of a string, left-justified.

Category

Display and formatting functions, String functions

Syntax

LJustify(string, length)

See also

CJustify , RJustify

Parameters

Parameter | Description
string | A string or a variable that contains one
length | Length of field in which to justify string

Example

<!--- This example shows how to use LJustify --->
<cfparam name = "jstring" default = "">

<cfif IsDefined("FORM.justifyString")>
   <cfset jstring = Ljustify(FORM.justifyString, 35)>
</cfif>
<html>
<head>
   <title>LJustify Example</title>
</head>
<body>

<h3>LJustify Function</h3>
<p>Enter a string, and it will be left justified within the sample field

<form action = "ljustify.cfm">
<p><input type = "Text" value = "<cfoutput>#jString#</cfoutput>"
 size = 35 name = "justifyString">

<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


Log

Description

Calculates the natural logarithm of a number. Natural logarithms are based on the constant e (2.71828182845904).

Return value

The natural logarithm of a number.

Category

Mathematical functions

Syntax

Log(number)

See also

Exp , Log10

Parameters

Parameter | Description
number | Positive real number for which to calculate the natural logarithm

Example

<h3>Log Example</h3>

<cfif IsDefined("FORM.number")>
   <cfoutput>
      <p>Your number, #FORM.number#
      <br>#FORM.number# raised to the E power: #exp(FORM.number)#
      <cfif FORM.number LTE 0><br>Enter a positive real number to get its
natural logarithm
         <cfelse><br>The natural logarithm    of #FORM.number#: #log(FORM.number)#
      </cfif>
      <cfif FORM.number LTE 0><br>Enter a positive real number to get its
logarithm to base 10
         <cfelse><br>The logarithm of #FORM.number# to base 10: #log10(FORM.number)#
      </cfif>
   </cfoutput>
</cfif>
<cfform action = "log.cfm">
Enter a number to see its value raised to the E power, its natural logarithm,
and the logarithm of number to base 10.
<cfinput type = "Text" name = "number" message = "You must enter a number"
validate = "float" required = "No">
<input type = "Submit" name = "">
</cfform>


Log10

Description

Calculates the logarithm of number, to base 10.

Return value

Number; the logarithm of number, to base 10.

Category

Mathematical functions

Syntax

Log10(number)

See also

Exp , Log

Parameters

Parameter | Description
number | Positive real number for which to calculate the logarithm

Example

<h3>Log10 Example</h3>
<cfif IsDefined("FORM.number")>
   <cfoutput>
      <p>Your number, #FORM.number#
      <br>#FORM.number# raised to the E power: #exp(FORM.number)#
      <cfif FORM.number LTE 0><br>You must enter a positive real number to
see the natural logarithm of that number
      <cfelse><br>The natural logarithm of #FORM.number#: #log(FORM.number)#
      </cfif>
      <cfif #FORM.number# LTE 0><br>You must enter a positive real number to
see the logarithm of that number to base 10
      <cfelse><br>The logarithm of #FORM.number# to base 10: #log10(FORM.number)#
      </cfif>
   </cfoutput>
</cfif>
<cfform action = "log10.cfm">
Enter a number to find its value raised to the E power, its natural
logarithm, and the logarithm of number to base 10.
<cfinput type = "Text" name = "number" message = "You must enter a number"
validate = "float" required = "No">
<input type = "Submit" name = "">
</cfform>


LSCurrencyFormat

Description

Formats a number in a locale-specific currency format. To manage euro currency values, use the LSEuroCurrencyFormat function.

Return value

A formatted currency value.

Category

Display and formatting functions, International functions

Syntax

LSCurrencyFormat(number [, type ])

See also

LSEuroCurrencyFormat , SetLocale

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. If a negative number is passed to it, it returns a negative number. If type = "local", it returns the value in the current locale’s standard format. If type = "international", it returns the value in the current locale’s international standard format. This function uses Java standard locale formatting rules on all platforms.

Parameters

Parameter
Description
number
Currency value
type
  • local: the currency format and currency symbol used in the locale.
    • - With JDK 1.3, the default for Euro Zone countries is their local currency.
    - With JDK 1.4, the default for Euro Zone countries is the euro.
  • international: the international standard currency format and currency symbol of the locale.
  • none: the currency format used in the locale; no currency symbol

Usage

This function uses Java standard locale formatting rules on all platforms.


Currency output

The following table shows sample currency output:

Locale
Type = Local
Type = International
Type = None
Dutch (Belgian)
100.000,00 BF

BEF100.000,00

100.000,00
Dutch (Standard)
fl 100.000,00

NLG100.000,00

100.000,00
English (Australian)
$100,000.00

AUD100,000.00

100,000.00
English (Canadian)
$100,000.00

CAD100,000.00

100,000.00
English (New Zealand)
$100,000.00

NZD100,000.00

100,000.00
English (UK)
£100,000.00

GBP100,000.00

100,000.00
English (US)
$100,000.00

USD100,000.00

100,000.00
French (Belgian)
100.000,00 FB

BEF100.000,00

100.000,00
French (Canadian)
100 000,00 $

CAD100 000,00

100 000,00
French (Standard)
100 000,00 F

FRF100 000,00

100 000,00
French (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
German (Austrian)
öS 100.000,00

ATS100.000,00

100.000,00
German (Standard)
100.000,00 DM

DEM100.000,00

100.000,00
German (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
Italian (Standard)
L. 10.000.000

ITL10.000.000

10.000.000
Italian (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
Norwegian (Bokmal)
kr 100 000,00

NOK100 000,00

100 000,00
Norwegian (Nynorsk)
kr 100 000,00

NOK100 000,00

100 000,00
Portuguese (Brazilian)
R$100.000,00

BRC100.000,00

100.000,00
Portuguese (Standard)
R$100.000,00

BRC100.000,00

100.000,00
Spanish (Mexican)
$100,000.00

MXN100,000.00

100,000.00
Spanish (Modern)
10.000.000 Pts

ESP10.000.000

10.000.000
Spanish (Standard)
10.000.000 Pts

ESP10.000.000

10.000.000
Swedish
100.000,00 kr

SEK100.000,00

100.000,00

Note: ColdFusion maps Spanish (Modern) to the Spanish (Standard) format.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSCurrencyFormat Example</h3>
<p>LSCurrencyFormat returns a currency value using the locale
convention. Default value is "local."
<!--- loop through list of locales; show currency values for 100,000 units --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><b><I>#locale#</I></b><br>
      Local: #LSCurrencyFormat(100000, "local")#<br>
      International: #LSCurrencyFormat(100000, "international")#<br>
      None: #LSCurrencyFormat(100000, "none")#<br>
      <hr noshade>
   </cfoutput>
</cfloop>


LSDateFormat

Description

Formats the date part of a date/time value in a locale-specific format.

Return value

A formatted date/time value. If no mask is specified, the value is formatted according to the locale setting of the client computer.

Category

Date and time functions, Display and formatting functions, International functions

Syntax

LSDateFormat(date [, mask ])

History

New in ColdFusion MX:

  • This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.
  • This function supports the short, medium, long, and full mask attribute options.

Parameters

Parameter
Description
date
A date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
mask
Characters that show how ColdFusion displays the date:
  • d: Day of month. Digits; no leading zero for single-digit days
  • dd: Day of month. Digits; leading zero for single-digit days
  • ddd: Day of week. Three-letter abbreviation
  • dddd: Day of week. Full name
  • m: Month. Digits; no leading zero for single-digit months
  • mm: Month. Digits; leading zero for single-digit months
  • mmm: Month. Three-letter abbreviation
  • mmmm: Month. Full name
  • y: Year. Last two digits; no leading zero for years less than 10
  • yy: Year. Last two digits; leading zero for years less than 10
  • yyyy: Year. Four digits
  • gg: Period/era string. Not processed. Reserved for future use
  • short
  • medium
  • long
  • full
Default: the Java standard Medium format for the locale.
For more information on formats, see LSParseDateTime.

Usage

This function uses Java standard locale formatting rules on all platforms.

When passing date/time value as a string, enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

To calculate a difference between time zones, use the GetTimeZoneInfo function.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSDateFormat Example</h3>
<p>LSDateFormat formats the date part of a date/time value using the
locale convention.
<!--- loop through a list of locales; show date values for Now()--->
<cfloop list = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>

   <cfoutput><p><B><I>#locale#</I></B><br>
      #LSDateFormat(Now(), "mmm-dd-yyyy")#<br>
      #LSDateFormat(Now(), "mmmm d, yyyy")#<br>
      #LSDateFormat(Now(), "mm/dd/yyyy")#<br>
      #LSDateFormat(Now(), "d-mmm-yyyy")#<br>
      #LSDateFormat(Now(), "ddd, mmmm dd, yyyy")#<br>
      #LSDateFormat(Now(), "d/m/yy")#<br>
      #LSDateFormat(Now())#<br>
      <hr noshade>
   </cfoutput>
</cfloop>


LSEuroCurrencyFormat

Description

Formats a number in a locale-specific currency format.

Return value

A formatted value.

  • If the country of the current locale belongs to the Euro Zone (whose members have converted to the euro) the euro currency symbol displays in the formatted output. If the value is negative, the format includes a negative sign before the value or parentheses around the value, according to the formatting rules of the current locale.
  • If the country of the current locale is not in the Euro Zone, the currency symbol of the current locale displays. If the value is negative, the format includes a negative sign before the value or parentheses around the value, according to the formatting rules of the current locale.

Category

Display and formatting functions, International functions

Syntax

LSEuroCurrencyFormat(currency-number [, type ])

See also

LSParseEuroCurrency , LSCurrencyFormat , SetLocale

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms. This function determines whether the current locale’s country belongs to the Euro Zone (whose members have converted to the euro); if so, it displays the value in the locale’s euro format. (Earlier releases formatted output with the euro symbol regardless of the locale or Euro Zone membership.)

Parameters

Parameter
Description
currency-number
Currency value.
type
  • local: the currency format used in the locale. (Default.)
  • international: the international standard currency format of the locale.
    For example, EUR10.00
  • none: the currency format used in the locale; no currency symbol

Usage

This function uses Java standard locale formatting rules on all platforms.

For a list of the locale options that ColdFusion supports, see SetLocale .

To set the default display format of date, time, number, and currency values, use the SetLocale function.

The following example shows differences between earlier ColdFusion releases and ColdFusion MX in accepting input formats and displaying output:

<cfset oldlocale = SetLocale("German (Standard)")>
<cfoutput>
   New Locale = #getLocale()#
   <br>
   <cfset z= LSEuroCurrencyFormat(1234.56, "local")>
   <cfset x= LSParseEuroCurrency("EUR1.234,56")>
   <cfset y= LSIsCurrency("DEM1.234,56")>
   <cfset k= LSIsCurrency("EUR1.234,56")>
   <br>
   Euro CurrFormat  : #z# <br>
   Parsed Euro Value: #x#<br>
   IsCurrency(DEM):   #y#<br>
   IsCurrency(EUR):   #k#<br>
</cfoutput>

ColdFusion MX produces the following output:

New Locale = German (Standard)
Euro CurrFormat : 1.234,56 €
Parsed Euro Value: 1234.56
IsCurrency(DEM): NO
IsCurrency(EUR): YES

Earlier ColdFusion releases produce the following output:

New Locale = German (Standard)
Euro CurrFormat : 1.234,56 €
Parsed Euro Value: 1234.56
IsCurrency(DEM): YES
IsCurrency(EUR): NO


Currency output

The following table shows examples of currency output:

Locale
Type = local
Type = international
Type = none
Dutch (Belgian)
100.000,00

EUR100.000,00

100.000,00
Dutch (Standard)
👤.000,00

EUR100.000,00

100.000,00
English (Australian)
👤,000.00

EUR100,000.00

100,000.00
English (Canadian)
👤,000.00

EUR100,000.00

100,000.00
English (New Zealand)
👤,000.00

EUR100,000.00

100,000.00
English (UK)
👤,000.00

EUR100,000.00

100,000.00
English (US)
👤,000.00

EUR100,000.00

100,000.00
French (Belgian)
100.000,00 €

EUR100.000,00

100.000,00
French (Canadian)
100 000,00 €

EUR100 000,00

100 000,00
French (Standard)
100 000,00 €

EUR100 000,00

100 000,00
French (Swiss)
👤'000.00

EUR100'000.00

100'000.00
German (Austrian)
👤.000,00

EUR100.000,00

100.000,00
German (Standard)
100.000,00 €

EUR100.000,00

100.000,00
German (Swiss)
👤'000.00

EUR100'000.00

100'000.00
Italian (Standard)
㈊.000.000

EUR10.000.000

10.000.000
Italian (Swiss)
👤'000.00

EUR100'000.00

100'000.00
Norwegian (Bokmal)
👤 000,00

EUR100 000,00

100 000,00
Norwegian (Nynorsk)
👤 000,00

EUR100 000,00

100 000,00
Portuguese (Brazilian)
👤.000,00

EUR100.000,00

100.000,00
Portuguese (Standard)
👤.000,00

EUR100.000,00

100.000,00
Spanish (Mexican)
👤,000.00

EUR100,000.00

100,000.00
Spanish (Modern)
10.000.000 €

EUR10.000.000

10.000.000
Spanish (Standard)
10.000.000 €

EUR10.000.000

10.000.000
Swedish
100.000,00 €

EUR100.000,00

100.000,00

Note: ColdFusion uses the Spanish (Standard) formats for Spanish (Modern) and Spanish (Standard).

The following example shows how the function formats negative values. The format includes a negative sign before the value, or parentheses around the value, according to the formatting rules of the current locale.

Input value
Output if locale = French (Standard)
Output if locale = English (US)
-1234.56
-1 234,56 €

($1,234.56)

Example

<h3>LSEuroCurrencyFormat Example</h3>
<p>LSEuroCurrencyFormat returns a currency value using the locale
convention. Default value is "local."
<!--- loop through list of locales,show currency values for 100,000 units --->
<cfloop list = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><B><I>#locale#</I></B><br>
      Local: #LSEuroCurrencyFormat(100000, "local")#<br>
      International: #LSEuroCurrencyFormat(100000, "international")#<br>
      None: #LSEuroCurrencyFormat(100000, "none")#<br>
      <Hr noshade>
   </cfoutput>
</cfloop>


LSIsCurrency

Description

Determines whether a string is formatted as a locale-specific currency string.

Return value

True, if the current locale setting is that of a Euro Zone country, and the string is valid in the Euro Zone or non-Euro zone currency format; False, otherwise.

Category

Display and formatting functions, Decision functions, International functions

Syntax

LSIsCurrency(string)

See also

GetLocale , SetLocale

History

New in ColdFusion MX: This function might return a different result than in earlier releases. This function uses Java standard locale formatting rules on all platforms. This function determines whether the current locale’s country belongs to the Euro Zone, whose members have converted to the euro; if so, it displays the currency value in euros.

Parameters

Parameter | Description
string | A currency string or a variable that contains one.

Usage

For examples of ColdFusion code and output that shows differences between earlier ColdFusion releases and ColdFusion MX in accepting input formats and displaying output, see LSEuroCurrencyFormat .

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSIsCurrency Example</h3>

<cfif IsDefined("FORM.locale")>
<!--- if locale is defined, set locale to that entry --->
<cfset NewLocale = SetLocale(FORM.locale)>

<p>Is the value "<cfoutput>#FORM.myValue#</cfoutput>"
a proper currency value for <cfoutput>#GetLocale()#</cfoutput>?
<p>Answer: <cfoutput>#LSIsCurrency(FORM.myValue)#</cfoutput>
</cfif>

<p><form action = "LSIsCurrency.cfm">
<p>Select a locale for which you would like to check a currency value:
<!--- check the current locale for server --->
<cfset serverLocale = GetLocale()>


LSIsDate

Description

Determines whether a string is a date/time value that can be formatted in a locale-specific format.

Return value

True, if the string can be formatted as a date/time value in the current locale; False, otherwise.

Category

Date and time functions, Display and formatting functions, International functions

Syntax

LSIsDate(string)

See also

CreateDateTime , GetLocale , IsNumericDate , LSDateFormat , ParseDateTime , SetLocale

History

New in ColdFusion MX:

  • This function might return a different result than in earlier releases. This function uses Java standard locale formatting rules on all platforms.
  • This function accepts a dash or hyphen character only in the Dutch(Standard) and Portuguese (Standard) locales. If called this way (for example, LsIsDate("3-1-2002") in any other locale, this function returns False. (Earlier releases returned True.)
  • When using the SUN JRE 1.3.1 on an English(UK) locale, this function returns False for a date that has a one-digit month or day (for example, 1/1/01). To work around this, insert a zero in a one-digit month or day (for example, 01/01/01).

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

A date/time object is in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSIsDate Example</h3>
<cfif IsDefined("FORM.locale")>
   <!--- if locale is defined, set locale to that entry --->
   <cfset NewLocale = SetLocale(FORM.locale)>
   <p>Is the value "<cfoutput>#FORM.myValue#</cFOUTPUT>" a proper date
value for <cfoutput>#GetLocale()#</cfoutput>?
   <p>Answer: <cfoutput>#LSIsDate(FORM.myValue)#</cfoutput>
</cfif>
<p><form action = "LSIsDate.cfm">
<p>Select a locale for which you would like to check a date value:
<!--- check the current locale for server --->
<cfset serverLocale = GetLocale()>


LSIsNumeric

Description

Determines whether a string can be formatted in a locale-specific format.

Return value

True, if the string can be formatted in the current locale format; False, otherwise.

Category

Decision functions, International functions, String functions

Syntax

LSIsNumeric(string)

See also

GetLocale , SetLocale

History

New in ColdFusion MX: This function might return a different result than in earlier releases. This function uses Java standard locale formatting rules on all platforms.

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSIsNumeric Example</h3>

<cfif IsDefined("FORM.locale")>
<!--- if locale is defined, set locale to that entry --->
<cfset NewLocale = SetLocale(FORM.locale)>

<p>Is the value "<cfoutput>#FORM.myValue#</cFOUTPUT>"
a proper numeric value for <cfoutput>#GetLocale()#</cfoutput>?

<p>Answer: <cfoutput>#LSIsNumeric(FORM.myValue)#</cfoutput>
</cfif>

<p><form action = "LSIsNumeric.cfm">

<p>Select a locale for which to check a numeric value:
...


LSNumberFormat

Description

Formats a number in a locale-specific format.

Return value

A formatted number.

  • If no mask is specified, it returns the number formatted as an integer
  • If no mask is specified, truncates the decimal part; for example, it truncates 34.57 to 35
  • If the specified mask cannot correctly mask a number, it returns the number unchanged
  • If the parameter value is "" (an empty string), it returns 0.

Category

Display and formatting functions, International functions

Syntax

LSNumberFormat(number [, mask ])

See also

GetLocale , SetLocale

History

New in ColdFusion MX: If the specified mask format cannot correctly mask a number, this function returns the number unchanged. (In earlier releases, it truncated the number or threw an error.) (If no mask is specified, ColdFusion MX truncates the decimal part as ColdFusion 5 does. For example, it truncates 1234.567 to 1235.)

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.

Parameters

Parameter | Description
number | Number to format
mask | LSNumberFormat mask characters apply, except: dollar sign, comma, and dot are mapped to their locale-specific equivalents.

The following table lists the LSNumberFormat mask characters.

Character
Meaning
_
(Underscore.) Digit placeholder.
9
Digit placeholder. (Shows decimal places more clearly than _ .)
.
Location of a mandatory decimal point (or locale-appropriate symbol).
0
Located to the left or right of a mandatory decimal point. Pads with zeros.
( )
If number is less than zero, puts parentheses around the mask.
+
Puts plus sign before positive number; minus sign before negative number.
-
Puts space before positive number; minus sign before negative number.
,
Separates every third decimal place with a comma (or locale-appropriate symbol).
L,C
Left-justifies or center-justifies number within width of mask column. First character of mask must be L or C. Default: right-justified.
$
Puts a dollar sign (or locale-appropriate symbol) before formatted number. First character of mask must be the dollar sign ($).
^
Separates left and right formatting.

Note: If you do not specify a sign for the mask, positive and negative numbers do not align in columns. To put a plus sign or space before positive numbers and a minus sign before negative numbers, use the plus or hyphen mask character, respectively.

Usage

This function uses Java standard locale formatting rules on all platforms.

The position of symbols in format masks determines where the codes take effect. For example, if you put a dollar sign at the far left of a format mask, ColdFusion displays a dollar sign at the left edge of the formatted number. If you separate the dollar sign on the left edge of the format mask by at least one underscore, ColdFusion displays the dollar sign just to the left of the digits in the formatted number.

These examples show how symbols determine formats:

Number
Mask
Result
4.37

$____.__

"$  4.37"

4.37

_$___.__

"  $4.37"

The positioning can also show where to put a minus sign for negative numbers:

Number
Mask
Result
-4.37

-____.__

"-  4.37"

-4.37

_-___.__

"  -4.37"

The positions for a symbol are: far left, near left, near right, and far right. The left and right positions are determined by the side of the decimal point on which the code character is shown. For formats that do not have a fixed number of decimal places, you can use a caret (^) to separate the left fields from the right.

An underscore determines whether the code is placed in the far or near position. Most code characters’ effect is determined by the field in which they are located. This example shows how to specify where to put parentheses to display negative numbers:

Number
Mask
Result
3.21

C(__^__)

"( 3.21 )"

3.21

C__(^__)

" (3.21 )"

3.21

C(__^)__

"( 3.21) "

3.21

C__(^)__

" (3.21) "

To set the default display format of date, time, number, and currency values, use the SetLocale function.

When converting from string to double, to prevent rounding errors, this function adds a rounding factor of 1.5543122344752E-014 to the converted number. For example, without adding the rounding factor, converting the string value 1.275 to double with two digits of precision results in a value of 1.27499999999999999, which would be rounded up to 1.27. By adding the rounding factor, the conversion correctly results in a value of 1.28.

If you round off a double, such as 1.99499999999999999999999999999, where the last decimal is 10E-14, the rounding factor can cause an incorrect result.

Example

<h3>LSNumberFormat Example</h3>
<p>LSNumberFormat returns a number value using the locale convention.
<!--- loop through a list of locales and show number values --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><b><i>#locale#</i></b><br>
      #LSNumberFormat(-1234.5678, "_________")#<br>
      #LSNumberFormat(-1234.5678, "_________.___")#<br>
      #LSNumberFormat(1234.5678, "_________")#<br>
      #LSNumberFormat(1234.5678, "_________.___")#<br>
      #LSNumberFormat(1234.5678, "$_(_________.___)")#<br>
      #LSNumberFormat(-1234.5678, "$_(_________.___)")#<br>
      #LSNumberFormat(1234.5678, "+_________.___")#<br>
      #LSNumberFormat(1234.5678, "-_________.___")#<br>
   </cfoutput>
</cfloop>


LSParseCurrency

Description

Formats a locale-specific currency string as a number. Attempts conversion through each of the default currency formats (none, local, international).

Return value

A formatted number that matches the value of the string.

Category

International functions, String functions

Syntax

LSParseCurrency(string)

See also

LSCurrencyFormat , LSParseEuroCurrency

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.

Parameters

Parameter | Description
string | A locale-specific string a variable that contains one

Usage

This function uses Java standard locale formatting rules on all platforms.

This function is similar to LSParseEuroCurrency, but it parses a non-euro currency string for a locale.


Currency output

The following table shows examples of currency output:

Locale

Format = local
Format =
international

Format = none
Dutch (Belgian)
100.000,00 BF

BEF100.000,00

100.000,00
Dutch (Standard)
fl 100.000,00

NLG100.000,00

100.000,00
English (Australian)
$100,000.00

AUD100,000.00

100,000.00
English (Canadian)
$100,000.00

CAD100,000.00

100,000.00
English (New Zealand)
$100,000.00

NZD100,000.00

100,000.00
English (UK)
£100,000.00

GBP100,000.00

100,000.00
English (US)
$100,000.00

USD100,000.00

100,000.00
French (Belgian)
100.000,00 FB

BEF100.000,00

100.000,00
French (Canadian)
100 000,00 $

CAD100 000,00

100 000,00
French (Standard)
100 000,00 F

FRF100 000,00

100 000,00
French (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
German (Austrian)
öS 100.000,00

ATS100.000,00

100.000,00
German (Standard)
100.000,00 DM

DEM100.000,00

100.000,00
German (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
Italian (Standard)
L. 10.000.000

ITL10.000.000

10.000.000
Italian (Swiss)
SFr. 100'000.00

CHF100'000.00

100'000.00
Norwegian (Bokmal)
kr 100 000,00

NOK100 000,00

100 000,00
Norwegian (Nynorsk)
kr 100 000,00

NOK100 000,00

100 000,00
Portuguese (Brazilian)
R$100.000,00

BRC100.000,00

100.000,00
Portuguese (Standard)
R$100.000,00

BRC100.000,00

100.000,00
Spanish (Mexican)
$100,000.00

MXN100,000.00

100,000.00
Spanish (Modern)
10.000.000 Pts

ESP10.000.000

10.000.000
Spanish (Standard)
10.000.000 Pts

ESP10.000.000

10.000.000
Swedish
100.000,00 kr

SEK100.000,00

100.000,00

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSParseCurrency Example</h3>
<p>LSParseCurrency coverts a locale-specific currency string to a number.
Attempts conversion through each of the three default currency formats.
<!--- loop through a list of locales; show currency values for 123,456 units --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><B><I>#locale#</I></B><br>
      Local: #LSCurrencyFormat(123456, "local")#<br>
      Currency: #LSParseCurrency(LSCurrencyFormat(123456,"local"))#<br>
      International: #LSCurrencyFormat(123456, "international")#<br>
      None: #LSCurrencyFormat(123456, "none")#<br>
      <hr noshade>
   </cfoutput>
</cfloop>


LSParseDateTime

Description

Formats a date/time string in a locale-specific format. Does not parse POP date/time objects.

Return value

A formatted date/time value.

Category

Date and time functions, Display and formatting functions, International functions, String functions

Syntax

LSParseDateTime(date/time-string)

See also

LSDateFormat , ParseDateTime , SetLocale

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.

New in ColdFusion MX: ColdFusion processes the date/time string parameter value differently than in earlier releases:

  • If a time zone specified in the date/time string parameter is different from the time zone setting of the ColdFusion Server computer, ColdFusion adjusts the time value to its equivalent in the time zone of the ColdFusion Server computer.
  • If a time zone is not specified in the date/time string parameter, ColdFusion does not adjust the time value.

Macromedia recommends that, when developing an application, you evaluate the entered time string for a time zone setting; ensure that your application adjusts the value, if necessary. (To do this, you can use a cfcatch tag.)

Parameters

Parameter | Description
date/time-string | A string a variable that contains one, in a format that is readable in the current locale. Default: English (US) locale.

Usage

This function uses Java standard locale formatting rules on all platforms.

ColdFusion uses the following date/time string length formats:

  • Short: all numeric. For example: "12/25/01", "3:30pm"
  • Medium: abbreviated month name. For example: "Jan 12, 1952"
  • Long: month spelled out. For example: "January 12, 1952", "3:30:32pm"
  • Full: Month and day spelled out. For example: "Tuesday, April 12, 1952 AD", "3:30:42pm PST"

You can pass a date/time value to this function that is in the English (US) locale, in any of the following date or date/time formats:

Mask | Format | Example
Jan dd, yyyy | Date, Default | Jan 30, 2002
m/dd/yy | Date, Short | 1/30/02
m dd, yyyy | Date, Medium | Jan 30, 2002
mmmm dd, yyyy | Date, Long | January 30, 2002
Wednesday, mmmm dd, yyyy | Date, Full | Wednesday, January 30, 2002
Jan dd, yyyy 7:mm:ss AM | Date/time, Default | Jan 30, 2002 7:02:12 AM
m/dd/yy 7:mm AM | Date/time, Short | 1/30/02 7:02 AM
Jan dd, yyyy 7:mm:ss AM | Date/time, Medium | Jan 30, 2002 7:02:12 AM
mmmm dd, yyyy 7:mm:ss AM PST | Date/time, Long | January 30, 2002 7:02:12 AM PST
Wednesday, mmmm dd, yyyy 7:mm:ss AM PST | Date/time, Full | Wednesday, January 30, 2002 7:02:12 AM PST
{ts 'yyyy-07-06 hh:mm:ss'} | Date/time, None | {ts '2003-07-06 00:00:00'}

A date/time object is in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Note: This function does not accept POP dates.

Example

<h3>LSParseDateTime Example - returns a locale-specific date/time object</h3>
<!--- loop through a list of locales and show date values for Now()--->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><B><I>#locale#</I></B><br>
      <p>Locale-specific formats:
      <br>#LSDateFormat(Now(), "mmm-dd-yyyy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now(), "mmmm d, yyyy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now(), "mm/dd/yyyy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now(), "d-mmm-yyyy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now(), "ddd, mmmm dd, yyyy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now(), "d/m/yy")# #LSTimeFormat(Now())#<br>
      #LSDateFormat(Now())# #LSTimeFormat(Now())#<br>
   <p>Standard Date/Time:
   #LSParseDateTime("#LSDateFormat(Now())# #LSTimeFormat(Now())#")#<br>
   </cfoutput>
</cfloop>


LSParseEuroCurrency

Description

Formats a locale-specific currency string that contains the euro symbol (€) or sign (EUR) as a number. Attempts conversion through each of the default currency formats (none, local, international).

Return value

A formatted number that matches the value of the string.

Category

International functions, String functions

Syntax

LSParseEuroCurrency(currency-string)

See also

LSParseCurrency , LSEuroCurrencyFormat , SetLocale

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms. This function determines whether the current locale’s country belongs to the Euro Zone, whose members have converted to the euro; if so, it displays the currency value in euros.

Parameters

Parameter | Description
currency-string | Locale-specific string or a variable that contains one.

Usage

This function uses Java standard locale formatting rules on all platforms.

For example ColdFusion code and output that shows differences between earlier ColdFusion releases and ColdFusion MX in accepting input formats and displaying output, see LSEuroCurrencyFormat .

This function is similar to LSParseCurrency, but it parses only euro currency.

For a list of the locale options that ColdFusion supports, see SetLocale .

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSParseEuroCurrency Example</h3>
<p>LSParseEuroCurrency converts locale-specific currency string to
number. Attempts conversion through each default currency format.
<!--- Loop through a list of locales. Show currency values for 123,456 units. --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale("#locale#")>
   <cfoutput><p><B><I>#locale#</I></B><br>
      Local: #LSEuroCurrencyFormat(123456, "local")#<br>
      Currency Number:
      #LSParseEuroCurrency("EUR123456")#<br>
      International: #LSEuroCurrencyFormat(123456, "international")#<br>
      None: #LSEuroCurrencyFormat(123456, "none")#<br>
      <hr noshade>
   </cfoutput>
</cfloop>


LSParseNumber

Description

Formats a locale-specific string as a number.

Return value

A number that matches the value of the string.

Category

International functions, String functions

Syntax

LSParseNumber(string)

See also

LSParseDateTime , SetLocale

History

New in ColdFusion MX: This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

This function uses Java standard locale formatting rules on all platforms.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>LSParseNumber Example</h3>
<p>LSParseNumber converts a locale-specific string to a number.
Returns the number matching the value of string.
<!--- loop through a list of locales and show number values --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>

   <cfoutput><p><B><I>#locale#</I></B><br>
      #LSNumberFormat(-1234.5678, "_________")#<br>
      #LSNumberFormat(-1234.5678, "_________.___")#<br>
      #LSNumberFormat(1234.5678, "_________")#<br>
      #LSNumberFormat(1234.5678, "_________.___")#<br>
      #LSNumberFormat(1234.5678, "$_(_________.___)")#<br>
      #LSNumberFormat(-1234.5678, "$_(_________.___)")#<br>
      #LSNumberFormat(1234.5678, "+_________.___")#<br>
      #LSNumberFormat(1234.5678, "-_________.___")#<br>
      The actual number:
         #LSParseNumber(LSNumberFormat(1234.5678, "_________"))#<br>
      <hr noshade>
   </cfoutput>
</cfloop>


LSTimeFormat

Description

Formats the time part of a date/time string in a locale-specific format.

Return value

A formatted time value.

Category

Date and time functions, Display and formatting functions, International functions

Syntax

LSTimeFormat(time [, mask ])

See also

LSParseDateTime

History

New in ColdFusion MX:

  • This function might return different formatting than in earlier releases. This function uses Java standard locale formatting rules on all platforms.
  • This function supports the short, medium, long, and full mask attribute options.

Parameters

Parameter
Description
string
  • A date/time value
  • A string that is convertible to a time value
A date/time object is in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
mask
Masking characters that determine the format:
  • h: Hours; no leading zero for single-digit hours (12-hour clock)
  • hh: Hours; leading zero for single-digit hours. (12-hour clock)
  • H: Hours; no leading zero for single-digit hours (24-hour clock)
  • HH: Hours; leading zero for single-digit hours (24-hour clock)
  • m: Minutes; no leading zero for single-digit minutes
  • mm: Minutes; leading zero for single-digit minutes
  • s: Seconds; no leading zero for single-digit seconds
  • ss: Seconds; leading zero for single-digit seconds
  • t: One-character time marker string, such as A or P.
  • tt: Multiple-character time marker string, such as AM or PM
  • short
  • medium
  • long
  • full

Usage

This function uses Java standard locale formatting rules on all platforms.

When passing date/time value as a string, enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

To calculate a difference between time zones, use the GetTimeZoneInfo function.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

If no seconds value is passed to this function, and the mask value is s, the default output seconds format is one zero; for example, lstimeformat(6:39, "h:m:s") returns 6:39:0. If the mask value is ss, it returns 6:39:00.

Example

<h3>LSTimeFormat Example</h3>

<p>LSTimeFormat returns a time value using the locale convention.

<!--- loop through a list of locales and show time values --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>

   <cfoutput><p><B><I>#locale#</I></B><br>
   #LSTimeFormat(Now())#<br>
   #LSTimeFormat(Now(), ‘hh:mm:ss’)#<br>
   #LSTimeFormat(Now(), ‘hh:mm:sst’)#<br>
   #LSTimeFormat(Now(), ‘hh:mm:sstt’)#<br>
   #LSTimeFormat(Now(), ‘HH:mm:ss’)#<br>
      <hr noshade>
   </cfoutput>

</cfloop>


LTrim

Description

Removes leading spaces from a string.

Return value

A copy of the string, without leading spaces.

Category

Display and formatting functions, String functions

Syntax

LTrim(string)

See also

RTrim , ToBase64

Parameters

Parameter | Description
string | A string or a variable that contains one

Example

<h3>LTrim Example</h3>

<cfif IsDefined("FORM.myText")>
<cfoutput>
<pre>
Your string:   "#FORM.myText#"
Your string:   "#Ltrim(FORM.myText)#"
(left trimmed)
</pre>
</cfoutput>
</cfif>

<form action = "ltrim.cfm">
<p>Type in some text, and it will be modified by Ltrim to remove
leading spaces from the left
<p><input type = "Text" name = "myText" value = "   TEST">

<p><input type = "Submit" name = "">
</form>


Max

Description

Determines the greater of two numbers.

Return value

The greater of two numbers.

Category

Mathematical functions

Syntax

Max(number1, number2)

See also

Min

Parameters

Parameter | Description
number1, number2 | Numbers

Example

<h3>Max Example</h3>
<cfif IsDefined("FORM.myNum1")>
   <cfif IsNumeric(FORM.myNum1) and IsNumeric(FORM.myNum2)>
   <p>The maximum of the two numbers is <cfoutput>#Max(FORM.myNum1,
    FORM.myNum2)#</cfoutput>
   <p>The minimum of the two numbers is <cfoutput>#Min(FORM.myNum1,
    FORM.myNum2)#</cfoutput>
   <cfelse>
   <p>Please enter two numbers
   </cfif>
</cfif>

<form action = "max.cfm">
<h3>Enter two numbers, see the maximum and minimum of them</h3>

Number 1 <input type = "Text" name = "MyNum1">
<br>Number 2 <input type = "Text" name = "MyNum2">

<br><input type = "Submit" name = "" value = "See results">
</form>


Mid

Description

Extracts a substring from a string.

Return value

A string; the set of characters from string, beginning at start, of length count.

Category

String functions

Syntax

Mid(string, start, count)

See also

Left , Len , Right

Parameters

Parameter | Description
string | A string or a variable that contains one. Must be single-quote or double-quote delimited.
start | A positive integer or a variable that contains one. Position at which to start count.
count | A positive integer or a variable that contains one. Number of characters to return. (0 is not valid, but it does not throw an error.)

Example

<h3>Mid Example</h3>
<cfif IsDefined("Form.MyText")>
<!--- if len is 0, then err --->
   <cfif Len(FORM.myText) is not 0>
      <cfif Len(FORM.myText) LTE FORM.RemoveChars>
      <p>Your string <cfoutput>#FORM.myText#</cFOUTPUT> only has
<cfoutput>#Len(FORM.myText)#</cfoutput> characters. You cannot output
the <cfoutput>#FORM.removeChars# </cfoutput> middle characters of this
string because it is not long enough
      <cfelse>

      <p>Your original string: <cfoutput>#FORM.myText#</cfoutput>
      <p>Your changed string, showing only the <cfoutput>#FORM.removeChars#
</cfoutput> middle characters:
      <cfoutput>#Mid(Form.myText, FORM.removeChars, Form.countChars)#</cfoutput>
      </cfif>


Min

Description

Determines the lesser of two numbers.

Return value

The lesser of two numbers.

Category

Mathematical functions

Syntax

Min(number1, number2)

See also

Max

Parameters

Parameter | Description
number1, number2 | Numbers

Example

<h3>Min Example</h3>
<cfif IsDefined("FORM.myNum1")>
   <cfif IsNumeric(FORM.myNum1) and IsNumeric(FORM.myNum2)>
   <p>The maximum of the two numbers is <cfoutput>#Max(FORM.myNum1,
    FORM.myNum2)#</cfoutput>
   <p>The minimum of the two numbers is <cfoutput>#Min(FORM.myNum1,
    FORM.myNum2)#</cfoutput>
   <cfelse>
   <p>Please enter two numbers
   </cfif>
</cfif>

<form action = "min.cfm">
<h3>Enter two numbers, and see the maximum and minimum of the two numbers</h3>

Number 1 <input type = "Text" name = "MyNum1">
<br>Number 2 <input type = "Text" name = "MyNum2">

<br><input type = "Submit" name = "" value = "See results">
</form>


Minute

Description

Extracts the minute value from a date/time object.

Return value

The ordinal value of the minute, in the range 0–59.

Category

Date and time functions

Syntax

Minute(date)

See also

DatePart , Hash , Second

Parameters

Parameter
Description
date
  • A date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<h3>Minute Example</h3>

<cfoutput>
The time is currently #TimeFormat(Now())#.
We are in hour #Hour(Now())#, Minute #Minute(Now())#
and Second #Second(Now())# of the day.
</cfoutput>


Month

Description

Extracts the month value from a date/time object.

Return value

The ordinal value of the month, in the range 1 (January) – 12 (December).

Category

Date and time functions

Syntax

Month(date)

See also

DatePart , MonthAsString , Quarter

Parameters

Parameter | Description
date | Date/time object, in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Note: You can pass the CreateDate function or the Now function as the date parameter of this function; for example: #Month(CreateDate(2001, 3, 3))#

Example

<h3>Month Example</h3>
<cfif IsDefined("FORM.year")>
More information about your date:
<cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
<cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
    #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(yourDate)# in the month of
    #MonthAsString(Month(yourDate))#, which has
    #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(yourDate)#
    (day #DayofYear(yourDate)# of #DaysinYear(yourDate)#). <br>
   <cfif IsLeapYear(Year(yourDat"))>This is a leap year
      <cfelse>This is not a leap year
   </cfif>
</cfoutput>
</cfif>


MonthAsString

Description

Determines the name of the month that corresponds to month_number.

Return value

A string; the name of a month.

Category

Date and time functions, String functions

Syntax

MonthAsString(month_number)

See also

DatePart , Month , Quarter

Parameters

Parameter | Description
month_number | An integer in the range 1 – 12.

Example

<h3>MonthAsString Example</h3>

<cfif IsDefined("FORM.year")>
<p>More information about your date:
<cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>

<cfoutput>
<p>Your date, #DateFormat(yourDate)#.
<br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
 #DayOfWeek(yourDate)# in the week.
<br>This is day #Day(YourDate)# in the month of
 #MonthAsString(Month(yourDate))#, which has
  #DaysInMonth(yourDate)# days.
<br>We are in week #Week(yourDate)# of #Year(yourDate)#
   (day #DayofYear(yourDate)# of #DaysinYear(yourDate)#). <br>
   <cfif IsLeapYear(Year(yourDate))>This is a leap year
      <cfelse>This is not a leap year
   </cfif>
</cfoutput>
</cfif>


Now

Description

Gets the current date and time of the computer running the ColdFusion server. The return value can be passed as a parameter to date functions such as DaysInYear or FirstDayOfMonth.

Return value

A date/time object; the current date and time of the computer running the ColdFusion server.

Category

Date and time functions

Syntax

Now()

See also

CreateDateTime , DatePart

Example

<h3>Now Example</h3>
<p>Now returns the current date and time as a valid date/time object.

<p>The current date/time value is <cfoutput>#Now()#</cfoutput>
<p>You can also represent this as <cfoutput>#DateFormat(Now())#,
 #TimeFormat(Now())#</cfoutput>


NumberFormat

Description

Creates a custom-formatted number value. Supports the numeric formatting used in the U.S. For international number formatting, see LSNumberFormat.

Return value

A formatted number value.

  • If no mask is specified, returns the value as an integer with a thousands separator
  • If the parameter value is "" (an empty string), it returns 0.

Category

Display and formatting functions

Syntax

NumberFormat(number [, mask ])

See also

DecimalFormat , DollarFormat , IsNumeric , LSNumberFormat

History

New in ColdFusion MX: If the mask format cannot correctly mask a number, this function returns the number unchanged. (It does not truncate the number nor throw an error.) (If no mask is selected, ColdFusion MX truncates the decimal part as ColdFusion 5 does. For example, it truncates 34.567 to 35.)

Parameters

Parameter | Description
number | A number.
mask | A string or a variable that contains one. Set of characters that determine how ColdFusion displays the number

The following table explains mask characters:

Mask character
Meaning
_ (underscore)
Optional. Digit placeholder.
9
Optional. Digit placeholder. (Shows decimal places more clearly than _.)
.
Location of a mandatory decimal point.
0
Located to the left or right of a mandatory decimal point. Pads with zeros.
( )
If number is less than zero, puts parentheses around the mask.
+
Puts plus sign before positive number; minus sign before negative number.
-
Puts a space before positive number; minus sign before negative number.
,
Separates every third decimal place with a comma.
L,C
Left-justifies or center-justifies number within width of mask column. First character of mask must be L or C. Default: right-justified.
$
Puts a dollar sign before formatted number. First character of mask must be the dollar sign ($).
^
Separates left and right formatting.

Note: If you do not specify a sign for the mask, positive and negative numbers do not align in columns. To put a plus sign or space before positive numbers and a minus sign before negative numbers, use the plus or minus sign, respectively.

Usage

This function uses Java standard locale formatting rules on all platforms.

The position of symbols in format masks determines where the codes take effect. For example, if you put a dollar sign at the far left of a format mask, ColdFusion displays a dollar sign at the left edge of the formatted number. If you separate the dollar sign on the left edge of the format mask by at least one underscore, ColdFusion displays the dollar sign just to the left of the digits in the formatted number.

These examples show how symbols determine formats:

Number
Mask
Result
4.37

$____.__

"$  4.37"

4.37

_$___.__

"  $4.37"

The positioning can also show where to place the minus sign for negative numbers:

Number
Mask
Result
-4.37

-____.__

"-  4.37"

-4.37

_-___.__

"  -4.37"

The positions for a symbol are: far left, near left, near right, and far right. The left and right positions are determined by the side of the decimal point on which the code character is shown. For formats that do not have a fixed number of decimal places, you can use a caret (^) to separate the left fields from the right.

An underscore determines whether the code is placed in the far or near position. Most code characters’ effect is determined by the field in which they are located. This example shows how to specify where to put parentheses to display negative numbers:

Number
Mask
Result
3.21

C(__^__)

"( 3.21 )"

3.21

C__(^__)

" (3.21 )"

3.21

C(__^)__

"( 3.21) "

3.21

C__(^)__

" (3.21) "

When converting from string to double, to prevent rounding errors, this function adds a rounding factor of 1.5543122344752E-014 to the converted number. For example, without adding the rounding factor, converting the string value 1.275 to double with two digits of precision results in a value of 1.27499999999999999, which would be rounded up to 1.27. By adding the rounding factor, the conversion correctly results in a value of 1.28.

If you round off a double such as 1.99499999999999999999999999999, where the last decimal is 10E-14, the rounding factor can cause an incorrect result.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Example

<h3>NumberFormat Example</h3>

<cfloop FROM = 1000 TO = 1020 INDEX = "counter">
<cfset CounterRoot2 = Evaluate(counter * sqr(2))>

<!--- Show result in default format, adding comma for thousands place;
and in custom format, displaying to two decimal places --->
<cfoutput>
<pre>#counter# * Square Root of 2: #NumberFormat(CounterRoot2,
  ‘_____.__’)#</pre>
<pre>#counter# * Square Root of 2: #NumberFormat(CounterRoot2)#</pre>
</cfoutput>
</cfloop>


ParagraphFormat

Description

Replaces characters in a string:

  • Single newline characters (CR/LF sequences) with spaces
  • Double newline characters with HTML paragraph tags (<p>)

Return value

A copy of the string, with characters converted.

Category

Display and formatting functions, String functions

Syntax

ParagraphFormat(string)

See also

StripCR

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

This function is useful for displaying data entered in textarea fields.

Example

<h3>ParagraphFormat Example</h3>
<p>Enter text into this textarea, and see it returned as HTML.
<cfif IsDefined("FORM.myTextArea")>
   <p>Your text area, formatted
   <p><cfoutput>#ParagraphFormat(FORM.myTextArea)#</cfoutput>
</cfif>
<!--- use #Chr(10)##Chr(13)# to simulate a line feed/carriage
return combination; i.e, a return --->
<form action = "paragraphformat.cfm">
<textArea name = "MyTextArea" cols = "35" ROWS = 8>
This is sample text and you see how it scrolls
<cfoutput>#Chr(10)##Chr(13)#</cfoutput>
From one line
<cfoutput>#Chr(10)##Chr(13)##Chr(10)##Chr(13)#</cfoutput>
to the next
</textArea>
<input type = "Submit" name = "Show me the HTML version">
</form>


ParameterExists

Description

This function is deprecated. Do not use it in new applications. Use the IsDefined function.

Determines whether a parameter exists. ColdFusion does not evaluate the argument.

History

New in ColdFusion MX: This function is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.


ParseDateTime

Description

Formats a date/time string according to the English (U.S.) locale convention. (To format a date/time string for other locales, use the LSParseDateTime function.)

Return value

An English (U.S.)-formatted date/time value.

Category

Date and time functions, Display and formatting functions

Syntax

ParseDateTime(date/time-string [, pop-conversion ] )

See also

IsDate , IsNumericDate , SetLocale

Parameters

Parameter
Description
date/time string
A date/time string or a variable that contains one.
A date/time object is in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.
pop-conversion
  • pop: formats a date/time string to UTC, for the English (US) locale
  • standard: function does no conversion. See the Usage section.

Usage

This function is similar to CreateDateTime, but it takes a string instead of enumerated date/time values. These functions are provided primarily to increase the readability of code in compound expressions.

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

To calculate a difference between time zones, use the GetTimeZoneInfo function.

To set the default display format of date, time, number, and currency values, use the SetLocale function.

Note: This function does not accept POP dates.

Example

<h3>ParseDateTime Example</h3>
<cfif IsDefined("FORM.theTestValue")>
   <cfif IsDate(FORM.theTestValue)>
   <h3>The expression <cfoutput>#DE(FORM.theTestValue)#</cfoutput> is a valid
date</h3>
   <p>The date, parsed for use as a date/time value:
    <cfoutput>#ParseDateTime(FORM.theTestValue)#
</cfoutput>


Pi

Description

Gets the mathematical constant p, accurate to 15 digits.

Return value

The number 3.14159265358979.

Category

Mathematical functions

Syntax

Pi()

See also

ASin , Cos , Sin , Tan

Example

<body>
<h3>Pi Example</h3>

Returns the number
<cfoutput>
#NumberFormat(Pi(), ‘_._______________’)#
</cfoutput>, the mathematical constant pi, accurate to 15 digits.


PreserveSingleQuotes

Description

Prevents ColdFusion from automatically escaping single quotation mark characters that are contained in a variable. ColdFusion does not evaluate the argument.

Return value

(None)

Category

Other functions

Syntax

PreserveSingleQuotes(variable)

History

New in ColdFusion MX: ColdFusion automatically escapes simple-variable, array-variable, and structure-variable references within a cfQuery tag body or block. (Earlier releases did not automatically escape array-variable references.)

Parameters

Parameter | Description
variable | Variable that contains a string in which to preserve single quotation marks.

Usage

This function is useful in SQL statements to defer evaluation of a variable reference until runtime. This prevents errors that result from the evaluation of a single-quote or apostrophe data character (for example, "Joe’s Diner") as a delimiter.

Example A: Consider this code:

<cfset mystring = "'Newton's Law', 'Fermat's Theorem'">
preservesinglequotes(#mystring#) is
<cfoutput>
#preservesinglequotes(mystring)#
</cfoutput>

The output is as follows:

preservesinglequotes(#mystring#) is 'Newton's Law', 'Fermat's Theorem'

Example B: Consider this code:

<cfset list0 = " '1','2''3' ">
<cfquery sql = "select * from foo where bar in (#list0#)">

ColdFusion escapes the single-quote characters in the list as follows:

""1"", ""2"", ""3""

The cfquery tag throws an error.

You code this function correctly as follows:

<cfquery sql = "select * from foo where bar in (#preserveSingleQuotes(list0)#)">

This function ensures that ColdFusion evaluates the code as follows:

'1', '2', '3'

Example

<h3>PreserveSingleQuotes Example</h3><p>This is a useful function for
   creating lists of information to return from a query. In this example,
   we pick the list of Centers in Suisun, San Francisco, and San Diego,
   using the SQL grammar IN to modify a WHERE clause, rather than looping
   through the result set after the query is run.
<cfset List = "'Suisun', 'San Francisco', 'San Diego'">
<cfquery name = "GetCenters" datasource = "cfsnippets">
   SELECT Name, Address1, Address2, City, Phone
   FROM Centers
   WHERE City IN (#PreserveSingleQuotes(List)#)
</cfquery>
<p>We found <cfoutput>#GetCenters.RecordCount#</cfoutput> records.
<cfoutput query = "GetCenters">
<p>#Name#<br>
#Address1#<br>
<cfif Address2 is not "">#Address2#
</cfif>
#City#<br>
#Phone#<br>
</cfoutput>


Quarter

Description

Calculates the quarter of the year in which a date falls.

Return value

An integer, 1–4.

Category

Date and time functions

Syntax

Quarter(date)

See also

DatePart , Month

Parameters

Parameter | Description
date | A date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<h3>Quarter Example</h3>

Today, <cfoutput>#DateFormat(Now())#</cfoutput>,
is in Quarter <cfoutput>#Quarter(Now())#</cfoutput>.


QueryAddColumn

Description

Adds a column to a query and populates its rows with the contents of a one-dimensional array. Pads query columns, if necessary, to ensure that all columns have the same number of rows.

Return value

The number of the column that was added.

Category

Query functions

Syntax

QueryAddColumn(query, column-name, array-name)

See also

QueryNew , QueryAddRow , QuerySetCell

History

New in ColdFusion MX: If a user attempts to add a column whose name is invalid, ColdFusion throws an error. (In earlier releases, ColdFusion permitted the add operation, but the user could not reference the column after adding it.)

Parameters

Parameter | Description
query | Name of a query that was created with QueryNew.
column-name | Name of the new column.
array-name | Name of an array whose elements are to populate the new column.

Usage

You can add columns to query objects such as queries retrieved with the cfquery tag or queries created with the QueryNew function. You cannot us the QueryAddColumn function on a cached query.

Useful for generating a query object from the arrays of output parameters that Oracle stored procedures can generate.

Example

<h3>QueryAddColumn Example</h3>
<p>This example adds three columns to a query object and then populates
the columns with the contents of three arrays.</p>
<p>After populating the query, the example shows, in tabular format,
the contents of the columns.</p>
<!--- make a query --->
<cfset myQuery = QueryNew("")>

<!--- create an array --->
<cfset FastFoodArray = ArrayNew(1)>
<cfset FastFoodArray[1] = "French Fries">
<cfset FastFoodArray[2] = "Hot Dogs">
<cfset FastFoodArray[3] = "Fried Clams">
<cfset FastFoodArray[4] = "Thick Shakes">

<!--- add a column to the query --->
<cfset nColumnNumber = QueryAddColumn(myQuery, "FastFood", FastFoodArray)>
<!--- create a second array --->
<cfset FineCuisineArray = ArrayNew(1)>
<cfset FineCuisineArray[1] = "Lobster">
<cfset FineCuisineArray[2] = "Flambe">
<!--- add a second column to the query --->
<cfset nColumnNumber2 = QueryAddColumn(myQuery, "FineCuisine", FineCuisineArray)>

<!--- create a third array --->
<cfset HealthFoodArray = ArrayNew(1)>
<cfset HealthFoodArray[1] = "Bean Curd">
<cfset HealthFoodArray[2] = "Yogurt">
<cfset HealthFoodArray[3] = "Tofu">

<!--- add a third column to the query --->
<cfset nColumnNumber3 = QueryAddColumn(myQuery, "HealthFood", HealthFoodArray)>

<table cellspacing = "2" cellpadding = "2" border = "0">
<tr>
  <th align = "left">Fast Food</th>
  <th align = "left">Fine Cuisine</th>
  <th align = "left">Health Food</th>
</tr>
<cfoutput query = "myQuery">
<tr>
  <td>#FastFood#</td>
  <td>#FineCuisine#</td>
  <td>#HealthFood#</td>
</tr>
</cfoutput>
</table>
<p><B>Note:</B> Because there are fewer elements in the Fine Cuisine
and Health Food arrays, QueryAddColumn added padding to the
corresponding columns in the query.</p>


QueryAddRow

Description

Adds a specified number of empty rows to a query.

Return value

The number of rows in a query

Category

Query functions

Syntax

QueryAddRow(query [, number ])

See also

QueryAddColumn , QueryAddRow , QuerySetCell , QueryNew

Parameters

Parameter | Description
query | Name of an executed query.
number | Number of rows to add to the query. Default: 1.

Example

<h3>QueryAddRow Example</h3>

<!--- start by making a query --->
<cfquery name = "GetCourses" datasource = "cfsnippets">
   SELECT Course_ID, Descript
   FROM Courses
</cfquery>
<p>The Query "GetCourses" has <cfoutput>#GetCourses.RecordCount#</cfoutput> rows.

<cfset CountVar = 0>
<cfloop CONDITION = "CountVar LT 15">
   <cfset temp = QueryAddRow(GetCourses)>
   <cfset CountVar = CountVar + 1>
   <cfset Temp = QuerySetCell(GetCourses, "Number", 100*CountVar)>
   <cfset CountVar = CountVar + 1>
   <cfset Temp = QuerySetCell(GetCourses, "Descript",
"Description of variable #Countvar#")>
</cfloop>

<P>After the QueryAddRow action, the query has
   <CFOUTPUT>#GetCourses.RecordCount#</CFOUTPUT>
   records.
   <CFOUTPUT query="GetCourses">
   <PRE>#Course_ID# #Course_Number# #Descript#</pre> </cfoutput>


QueryNew

Description

Creates an empty query.

Return value

An empty query with a set of columns, or an empty query.

Category

Query functions

Syntax

QueryNew(columnlist)

See also

QueryAddColumn , QueryAddRow , QuerySetCell

Parameters

Parameter | Description
columnlist | A string or a variable that contains one. Delimited list of columns, or an empty string.

Usage

If you specify an empty string, you can add a column to the query and populate its rows with the contents of a one-dimensional array using QueryAddColumn.

Example

<h3>QueryNew Example</h3>
<p>We will construct a new query with two rows:
<cfset myQuery = QueryNew("name, address, phone")>
<!--- make some rows in the query --->
<cfset newRow  = QueryAddRow(MyQuery, 2)>
<!--- set the cells in the query --->
<cfset temp = QuerySetCell(myQuery, "name", "Fred", 1)>
<cfset temp = QuerySetCell(myQuery, "address", "9 Any Lane", 1)>
<cfset temp = QuerySetCell(myQuery, "phone", "555-1212", 1)>
<cfset temp = QuerySetCell(myQuery, "name", "Jane", 2)>
<cfset temp = QuerySetCell(myQuery, "address", "14 My Street", 2)>
<cfset temp = QuerySetCell(myQuery, "phone", "555-1444", 2)>
<!--- output the query --->
<cfoutput query = "myQuery">
<pre>#name#   #address#   #phone#</pre>
</cfoutput>
To get any element in the query, we can output it individually
<cfoutput>
   <p>#MyQuery.name[2]#’s phone number: #MyQuery.phone[2]#
</cfoutput>


QuerySetCell

Description

Sets a cell to a value. If no row number is specified, the cell on the last row is set.

Return value

True, if successful; False, otherwise.

Category

Query functions

Syntax

QuerySetCell(query, column_name, value [, row_number ])

See also

QueryAddColumn , QueryAddRow , QueryNew

Parameters

Parameter | Description
query | Name of an executed query
column_name | Name of a column in the query
value | Value to set in the cell
row_number | Row number. Default: last row.

Example

<!--- This example shows the use of QueryAddRow and QuerySetCell --->

<!--- start by making a query --->
<cfquery name = "GetCourses" datasource = "cfsnippets">
   SELECT Course_ID, Descript
   FROM Courses
</cfquery>
<p>The Query "GetCourses" has <cfoutput>#GetCourses.RecordCount#</cfoutput> rows.

<cfset CountVar = 0>
<cfloop CONDITION = "CountVar LT 15">
   <cfset temp = QueryAddRow(GetCourses)>
   <cfset CountVar = CountVar + 1>
   <cfset Temp = QuerySetCell(GetCourses, "Number", 100*CountVar)>
   <cfset CountVar = CountVar + 1>
   <cfset Temp = QuerySetCell(GetCourses, "Descript",
"Description of variable #Countvar#")>
</cfloop>

<P>After the QueryAddRow action, the query has
   <CFOUTPUT>#GetCourses.RecordCount#</CFOUTPUT>
   records.
   <CFOUTPUT query="GetCourses">
   <PRE>#Course_ID# #Course_Number# #Descript#</pre> </cfoutput>


QuotedValueList

Description

Gets the values of each record returned from an executed query. ColdFusion does not evaluate the arguments.

Return value

A delimited list of the values of each record returned from an executed query. Each value is enclosed in single quotation marks.

Category

Query functions

Syntax

QuotedValueList(query.column [, delimiter ])

See also

ValueList

Parameters

Parameter | Description
query.column | Name of an executed query and column. Separate query name and column name with a period.
delimiter | A string or a variable that contains one. Character(s) that separate column data.

Example

<h3>QuotedValueList Example</h3>
<!--- use the contents of one query to create another dynamically --->
<cfset List = "‘BIOL’, ‘CHEM’">
<!--- first, get the department IDs in our list --->
<cfquery name = "GetDepartments" datasource = "cfsnippets">
   SELECT Dept_ID FROM Departments
   WHERE Dept_ID IN (#PreserveSingleQuotes(List)#)
</cfquery>
<!--- now, select the courses for that department based on the
quotedValueList produced from our previous query --->
<cfquery name = "GetCourseList" datasource = "cfsnippets">
   SELECT *
   FROM CourseList
   WHERE Dept_ID IN (#QuotedValueList(GetDepartments.Dept_ID)#)
</cfquery>
<!--- now, output the results --->
<cfoutput QUERY = "GetCourseList" >
<pre>#Course_ID#   #Dept_ID#   #CorNumber#   #CorName#</pre>
</cfoutput>


Rand

Description

Generates a random number.

Return value

A random decimal number, in the range 0 – 1.

Category

Mathematical functions

Syntax

Rand()

See also

Randomize , RandRange

Usage

To ensure greater randomness, call the Randomize function before calling Rand.

Example

<h3>Rand Example</h3>
<p>Rand() returns a random number in the range 0 to 1.
<p>Rand() returned: <cfoutput>#Rand()#</cfoutput>
<p><A HREF = "rand.cfm">Try again</A>


Randomize

Description

Seeds the ColdFusion random number generator with an integer number. Seeding the generator helps ensure that the Rand function generates highly random numbers.

Return value

A non-random decimal number, in the range 0 – 1.

Category

Mathematical functions

Syntax

Randomize(number)

See also

Rand , RandRange

Parameters

Parameter | Description
number | A number

Usage

Call this function before calling Rand. Although this function returns a decimal number, it is not a random number.

Example

<h3>Randomize Example</h3>
<p>Call Randomize to seed the random number generator. This helps
to ensure the randomness of numbers generated by Rand.
<cfif IsDefined("FORM.myRandomInt")>
   <cfif IsNumeric(FORM.myRandomInt)>
     <cfoutput><p><b>Seed value is #FORM.myRandomInt#</b>
      </cfoutput><br>
    <cfset r = Randomize(FORM.myRandomInt)>
     <cfloop index = "i" from = "1" to = "10" step = "1">
        <cfoutput>Next random number is #Rand()#</cfoutput><br>
     </cfloop><br>
   <cfelse>
      <p>Please enter a number.
   </cfif>
</cfif>
<form action = "randomize.cfm">
<p>Enter a number to seed the randomizer:
<input type = "Text" name = "MyRandomInt">
<p><input type = "Submit" name = "">
</form>


RandRange

Description

Generates a random integer between two specified numbers. Requests for random integers that are greater than 100,000,000 result in non-random numbers, to prevent overflow during internal computations.

Return value

A random integer

Category

Mathematical functions

Syntax

RandRange(number1, number2)

See also

Rand , Randomize

Parameters

Parameter | Description
number1, number2 | Integer numbers less than 100,000,000

Example

<h3>RandRange Example</h3>
<p>RandRange returns an integer between two specified integers.
<cfif IsDefined("FORM.myInt")>
   <p>RandRange returned:
      <cfoutput>#RandRange(FORM.myInt, FORM.myInt2)#</cfoutput>
</cfif>

<cfform action = "randRange.cfm">
<p>Enter a number to seed the randomizer:
<cfinput type = "Text" name = "MyInt" value = "1" RANGE = "1,100000000"
 message = "Please enter a value between 1 and 100,000,000"
  validate = "integer" required = "Yes">
<cfinput type = "Text" name = "MyInt2" value = "500" RANGE = "1,100000000"
 message = "Please enter a value between 1 and 100,000,000"
  validate = "integer" required = "Yes">
<p><input type = "Submit" name = "">
</cfform>


REFind

Description

Uses a regular expression (RE) to search a string for a pattern. The search is case sensitive.

For more information on regular expressions, including escape sequences, anchors, and modifiers, see Developing ColdFusion MX Applications with CFML.

Return value

Depends on the value of the returnsubexpressions parameter:

  • If returnsubexpressions = "False":
    • The position in the string where the match begins
    • 0, if the regular expression is not matched in the string
  • If returnsubexpressions = "True": a structure that contains two arrays, len and pos. The array elements are as follows:
    • If the regular expression is found in the string, the first element of the len and pos arrays contains the length and position, respectively, of the first match of the entire regular expression.
      If the regular expression contains parentheses that group subexpressions, each subsequent array element contains the length and position, respectively, of the first occurrence of each group.
    • If the regular expression is not found in the string, the first element of the len and pos arrays contains 0.

Category

String functions

Syntax

REFind(reg_expression, string [, start ]    [, returnsubexpressions ] )

See also

Find , FindNoCase , REFindNoCase , REReplace , REReplaceNoCase

Parameters

Parameter
Description
reg_expression
Regular expression for which to search. Case-sensitive.
string
A string, or a variable that contains one, in which to search.
start
Optional. A positive integer, or a variable that contains one. Position in the string at which to start search. Default: 1.
returnsubexpressions
Optional. Boolean. Whether to return substrings of reg_expression, in arrays named len and pos:
  • True: if the regular expression is found, the first array element contains the length and position, respectively, of the first match.
    If the regular expression contains parentheses that group subexpressions, each subsequent array element contains the length and position, respectively, of the first occurrence of each group.
    If the regular expression is not found, the arrays each contain one element with the value 0.
  • False: the function returns the position in the string where the match begins. Default.

Usage

This function finds the first occurrence of a regular expression in a string. To find the second and subsequent instances of the expression or of subexpressions in it, you call this function more than once, each time with a different start position. To determine the next start position, use the returnsubexpressions parameter, and add the value returned in the first element of the length array to the value in the first element of the position array.

Example

<h3>REFind Example</h3>
<p>This example shows the use of the REFind function with and without the
<i>returnsubexpressions</i> parameter set to True.
If you do not use the <i>returnsubexpressions</i> parameter,
REFind returns the position of the first occurrence of a regular
expression in a string starting from the specified position.
Returns 0 if no occurrences are found.</p>

<p>REFind("a+c+", "abcaaccdd"):
<cfoutput>#REFind("a+c+", "abcaaccdd")#</cfoutput></p>
<p>REFind("a+c*", "abcaaccdd"):
<cfoutput>#REFind("a+c*", "abcaaccdd")#</cfoutput></p>
<p>REFind("[[:upper:]]", "abcaacCDD"):
<cfoutput>#REFind("[[:upper:]]", "abcaacCDD")#</cfoutput></p>
<p>REFind("[\?&]rep = ", "report.cfm?rep = 1234&u = 5"):
   <cfoutput>#REFind("[\?&]rep = ", "report.cfm?rep = 1234&u = 5")#
   </cfoutput>
</p>
<!--- Set startPos to one; returnMatchedSubexpressions = TRUE --->
<hr size = "2" color = "#0000A0">
<p>If you use the <i>returnssubexpression</i> parameter, REFind returns the
position and length of the first occurrence of a regular expression
in a string starting from the specified position. The position and
length variables are stored in a structure. To access position and length
information, use the keys <i>pos</i> and <i>len</i>, respectively.</p>
<cfset teststring = "The cat in the hat hat came back!">
<p>The string in which the function is to search is:
<cfoutput><b>#teststring#</b></cfoutput>.</p>
<p>The first call to REFind to search this string is:
      <b>REFind("[A-Za-z]+",testString,1,"TRUE")</b></p>
<p>This function returns a structure that contains two arrays: pos and len.</p>
<p>To create this structure you can use a CFSET statement, for example: </p>
&lt;CFSET st = REFind("[[:alpha:]]",testString,1,"TRUE")&gt;
<cfset st = REFind("[[:alpha:]]",testString,1,"TRUE")>
<p>
   <cfoutput>
   The number of elements in each array: #ArrayLen(st.pos)#.
   </cfoutput></p>
<p><b>The number of elements in the pos and len arrays is always one
if you do not use parentheses in the regular expression.</b></p>
<p>The value of st.pos[1] is: <cfoutput>#st.pos[1]#.</cfoutput></p>
<p>The value of st.len[1] is: <cfoutput>#st.len[1]#.</cfoutput></p>
<p>
<cfoutput>
   Substring is <b>[#Mid(testString,st.pos[1],st.len[1])#]</B>
   </cfoutput></p>
<hr size = "2" color = "#0000A0">
<p>However, if you use parentheses in the regular expression, the first
element contains the position and length of the first instance
of the whole expression. The position and length of the first instance
of each parenthesized subexpression within is included in additional
array elements.</p>
<p>For example:
&lt;CFSET st1 = REFind("([[:alpha:]])[ ]+(\1)",testString,1,"TRUE")&gt;</p>
<cfset st1 = REFind("([[:alpha:]]+)[ ]+(\1)",testString,1,"TRUE")>
<p>The number of elements in each array is <cfoutput>#ArrayLen(st1.pos)#
</cfoutput>.</p>
<p>First whole expression match; position is
   <cfoutput>#st1.pos[1]#;
      length is #st1.len[1]#; whole expression match is
      <B>[#Mid(testString,st1.pos[1],st1.len[1])#]</B>
   </cfoutput></p>
<p>Subsequent elements of the arrays provide the position and length of
the first instance of each parenthesized subexpression therein.</p>
 <cfloop index = "i" from = "2" to = "#ArrayLen(st1.pos)#">
   <p><cfoutput>Position is #st1.pos[i]#; Length is #st1.len[i]#;
Substring is <B>[#Mid(testString,st1.pos[i],st1.len[i])#]
</B></cfoutput></p>
</cfloop><br>


REFindNoCase

Description

Uses a regular expression (RE) to search a string for a pattern, starting from a specified position. The search is case-insensitive.

For more information on regular expressions, including escape sequences, anchors, and modifiers, see Developing ColdFusion MX Applications with CFML.

Return value

Depends on the value of the returnsubexpressions parameter:

  • If returnsubexpressions = "False":
    • The position in the string where the match begins
    • 0, if the regular expression is not matched in the string
  • If returnsubexpressions = "True": a structure that contains two arrays, len and pos. The array elements are as follows:
    • If the regular expression is found in the string, the first element of the len and pos arrays contains the length and position, respectively, of the first match of the entire regular expression.
      If the regular expression contains parentheses that group subexpressions, each subsequent array element contains the length and position, respectively, of the first occurrence of each group.
    • If the regular expression is not found in the string, the first element of the len and pos arrays contains 0.

Category

String functions

Syntax

REFindNoCase(reg_expression, string [, start] [, returnsubexpressions] )

See also

Find , FindNoCase , REFind , REReplace , REReplaceNoCase

Parameters

Parameter
Description
reg_expression
Regular expression for which to search. Case-insensitive.
For more information, see Developing ColdFusion MX Applications with CFML.
string
A string or a variable that contains one. String in which to search.
start
Optional. A positive integer or a variable that contains one. Position at which to start search. Default: 1.
returnsubexpressions
Optional. Boolean. Whether to return substrings of reg_expression, in arrays named len and pos:
  • True: if the regular expression is found, the first array element contains the length and position, respectively, of the first match.
    If the regular expression contains parentheses that group subexpressions, each subsequent array element contains the length and position, respectively, of the first occurrence of each group.
    If the regular expression is not found, the arrays each contain one element with the value 0.
  • False: the function returns the position in the string where the match begins. Default.

Usage

This function finds the first occurrence of a regular expression in a string. To find the second and subsequent instances of the expression or of subexpressions in it, you call this function more than once, each time with a different start position. To determine the next start position, use the returnsubexpressions parameter, and add the value returned in the first element of the length array to the value in the first element of the position array.

Example

<h3>REFindNoCase Example</h3>
<p>This example demonstrates the use of the REFindNoCase function with and
without the <i>returnsubexpressions</i> parameter set to True.</p>
<p>If you do not use the <i>returnsubexpressions</i> parameter, REFindNoCase
returns the position of the first occurrence of a regular expression
in a string starting from the specified position. Returns 0 if no
occurrences are found. </p>
<p>REFindNoCase("a+c+", "abcaaccdd"):
<cfoutput>#REFindNoCase("a+c+", "abcaaccdd")#</cfoutput></p>
<p>REFindNoCase("a+c*", "abcaaccdd"):
<cfoutput>#REFindNoCase("a+c*", "abcaaccdd")#</cfoutput></p>
<p>REFindNoCase("[[:alpha:]]+", "abcaacCDD"):
<cfoutput>#REFindNoCase("[[:alpha:]]+", "abcaacCDD")#</cfoutput></p>
<p>REFindNoCase("[\?&]rep = ", "report.cfm?rep = 1234&u = 5"):
<cfoutput>#REFindNoCase("[\?&]rep = ", "report.cfm?rep = 1234&u = 5")#
</cfoutput></p>
<!--- Set startPos to one; returnMatchedSubexpressions = True --->
<hr size = "2" color = "#0000A0">
<p>If you do use the <i>returnssubexpression</i> parameter, REFindNoCase returns
the position and length of the first occurrence of a regular expression
in a string starting from the specified position. The position and length
variables are stored in a structure. To access position and length
information, use the keys <i>pos</i> and <i>len</i>, respectively.</p>

<cfset teststring = "The cat in the hat hat came back!">
<p>The string in which the function is to search is:
<cfoutput><b>#teststring#</b></cfoutput>.</p>
<p>The first call to REFindNoCase to search this string is:
<b>REFindNoCase("[[:alpha:]]+",testString,1,"True")</b></p>
<p>This function returns a structure that contains two arrays: pos and len.</p>
<p>To create this structure you can use a CFSET statement,
for example:</p>
&lt;CFSET st = REFindNoCase("[[:alpha:]]+",testString,1,"True")&gt;
<cfset st = REFindNoCase("[[:alpha:]]+",testString,1,"True")>
<p>
   <cfoutput>
   The number of elements in each array: #ArrayLen(st.pos)#.
   </cfoutput></p>
<p><b>The number of elements in the pos and len arrays will always be one,
if you do not use parentheses to denote subexpressions in the regular
expression.</b></p>
<p>The value of st.pos[1] is: <cfoutput>#st.pos[1]#.</cfoutput></p>
<p>The value of st.len[1] is: <cfoutput>#st.len[1]#.</cfoutput></p>
<p>
   <cfoutput>
   Substring is <b>[#Mid(testString,st.pos[1],st.len[1])#]</B>
   </cfoutput></p>
<hr size = "2" color = "#0000A0">
<p>However, if you use parentheses to denote subexpressions in the regular
expression, the first element contains the position and length of
the first instance of the whole expression. The position and length
of the first instance of each subexpression within will be included
in additional array elements.</p>
<p>For example:
&lt;CFSET st1 = REFindNoCase("([[:alpha:]]+)[ ]+(\1)",testString,1,"True")&gt;</p>
<cfset st1 = REFindNoCase("([[:alpha:]]+)[ ]+(\1)",testString,1,"True")>

<p>The number of elements in each array is
<cfoutput>
   #ArrayLen(st1.pos)#
</cfoutput>.</p>

<p>First whole expression match; position is
<cfoutput>
   #st1.pos[1]#; length is #st1.len[1]#;
   whole expression match is <B>[#Mid(testString,st1.pos[1],st1.len[1])#]</B>
</cfoutput></p>

<p>Subsequent elements of the arrays provide the position and length of the
first instance of each parenthesized subexpression therein.</p>
 <cfloop index = "i" from = "2" to = "#ArrayLen(st1.pos)#">
   <p><cfoutput>Position is #st1.pos[i]#; Length is #st1.len[i]#;
   Substring is <B>[#Mid(testString,st1.pos[i],st1.len[i])#]</B>
   </cfoutput></p>
</cfloop><br>


RemoveChars

Description

Removes characters from a string.

Return value

A copy of the string, with count characters removed from the specified start position. If no characters are found, returns zero.

Category

String functions

Syntax

RemoveChars(string, start, count)

See also

Insert , Len

Parameters

Parameter | Description
string | A string or a variable that contains one. String in which to search.
start | A positive integer or a variable that contains one. Position at which to start search.
count | Number of characters to remove

Example

<h3>RemoveChars Example</h3>
Returns a string with <I>count</I> characters removed from the
start position. Returns 0 if no characters are found.

<cfif IsDefined("FORM.myString")>
   <cfif Evaluate(FORM.numChars + FORM.start)
    GT Len(FORM.myString)>
      <p>Your string is only <cfoutput>#Len(FORM.myString)#
       </cfoutput> characters long.
      Please enter a longer string, select fewer characters to remove or
      begin earlier in the string.
   <cfelse>
      <cfoutput>
      <p>Your original string:    #FORM.myString#
      <p>Your modified string:   #RemoveChars(FORM.myString,
       FORM.numChars, FORM.start)#
      </cfoutput>


RepeatString

Description

Creates a string that contains a specified number of repetitions of the specified string.

Return value

A string.

Category

String functions

Syntax

RepeatString(string, count)

See also

CJustify , LJustify , RJustify

Parameters

Parameter | Description
string | A string or a variable that contains one
count | Number of repeats

Example

<h3>RepeatString Example</h3>
<p>RepeatString returns a string created from <I>string</I>, repeated
a specified number of times.
<ul>
   <li>RepeatString("-", 10): <cfoutput>#RepeatString("-", 10)#</cfoutput>
   <li>RepeatString("&lt;BR&gt;", 3): <cfoutput>#RepeatString("<br>", 3)#
</cfoutput>
   <li>RepeatString("", 5): <cfoutput>#RepeatString("", 5)#</cfoutput>
   <li>RepeatString("abc", 0): <cfoutput>#RepeatString("abc", 0)#</cfoutput>
   <li>RepeatString("Lorem Ipsum", 2):
    <cfoutput>#RepeatString("Lorem Ipsum", 2)#</cfoutput>
</ul>


Replace

Description

Replaces occurrences of substring1 in a string with substring2, in a specified scope. The search is case-sensitive.

Return value

The string, after making replacements.

Category

String functions

Syntax

Replace(string, substring1, substring2 [, scope ])

See also

Find , REFind , ReplaceNoCase , ReplaceList , REReplace

Parameters

Parameter
Description
string
A string or a variable that contains one. String in which to search
substring1
A string or a variable that contains one. String for which to search
substring2
String that replaces substring1
scope
  • one: replace the first occurrence (default)
  • all: replace all occurrences

Example

<h3>Replace Example</h3>

<p>The Replace function returns <I>string</I> with <I>substring1</I>
replaced by <I>substring2</I> in the specified scope. This
is a case-sensitive search.

<cfif IsDefined("FORM.MyString")>
<p>Your original string, <cfoutput>#FORM.MyString#</cfoutput>
<p>You wanted to replace the substring <cfoutput>#FORM.MySubstring1#
</cfoutput>
with the substring <cfoutput>#FORM.MySubstring2#</cfoutput>.
<p>The result: <cfoutput>#Replace(FORM.myString,
FORM.MySubstring1, FORM.mySubString2)#</cfoutput>
</cfif>


ReplaceList

Description

Replaces occurrences of the elements from a delimited list in a string with corresponding elements from another delimited list. The search is case-sensitive.

Return value

A copy of the string, after making replacements.

Category

List functions, String functions

Syntax

ReplaceList(string, list1, list2)

See also

Find , REFind , Replace , REReplace

Parameters

Parameter | Description
string | A string, or a variable that contains one, within which to replace substring
list1 | Comma-delimited list of substrings for which to search
list2 | Comma-delimited list of replacement substrings

Usage

The list of substrings to replace is processed sequentially. If a list1 element is contained in list2 elements, recursive replacement might occur. The second example shows this.

Example

<p>The Replacelist function returns <I>string</I> with
<I>substringlist1</I> (e.g. "a,b") replaced by <I>substringlist2</I>
(e.g. "c,d") in the specified scope.
<cfif IsDefined("FORM.MyString")>
<p>Your original string, <cfoutput>#FORM.MyString#</cfoutput>
<p>You wanted to replace the substring <cfoutput>#FORM.MySubstring1#
 </cfoutput>
with the substring <cfoutput>#FORM.MySubstring2#</cfoutput>.
<p>The result: <cfoutput>#Replacelist(FORM.myString,
FORM.MySubstring1, FORM.mySubString2)#</cfoutput>
</cfif>
<form action = "replacelist.cfm" method="post">
<p>String 1
<br><input type = "Text" value = "My Test String" name = "MyString">
<p>Substring 1 (find this list of substrings)
<br><input type = "Text" value = "Test, String" name = "MySubstring1">
<p>Substring 2 (replace with this list of substrings)
<br><input type = "Text" value = "Replaced, Sentence" name = "MySubstring2">
<p><input type = "Submit" value = "Replace and display" name = "">
</form>

<h3>Replacelist Example Two</h3>
<cfset stringtoreplace = "The quick brown fox jumped over the lazy dog.">
<cfoutput>
   #replacelist(stringtoreplace,"dog,brown,fox,black", "cow,black,ferret,white")#
</cfoutput>


ReplaceNoCase

Description

Replaces occurrences of substring1 with substring2, in the specified scope. The search is case-insensitive.

Return value

A copy of the string, after making replacements.

Category

String functions

Syntax

ReplaceNoCase(string, substring1, substring2 [, scope ])

See also

Find , REFind , Replace , ReplaceList , REReplace

Parameters

Parameter
Description
string
A string within which to replace substring
substring1
String, or a variable that contains one, to replace.
substring2
String or a variable that contains one, that replaces substring1
scope
  • one: Replace the first occurrence (default)
  • all: Replace all occurrences

Example

<h3>ReplaceNoCase Example</h3>
<p>The ReplaceNoCase function returns <I>string</I> with <I>substring1</I>
replaced by <I>substring2</I> in the specified scope.
The search/replace is case-insensitive.

<cfif IsDefined("FORM.MyString")>
<p>Your original string, <cfoutput>#FORM.MyString#</cfoutput>
<p>You wanted to replace the substring <cfoutput>#FORM.MySubstring1#
 </cfoutput>
with the substring <cfoutput>#FORM.MySubstring2#</cfoutput>.
<p>The result: <cfoutput>#ReplaceNoCase(FORM.myString,
FORM.MySubstring1, FORM.mySubString2)#</cfoutput>
</cfif>


REReplace

Description

Uses a regular expression (RE) to search a string for a string pattern and replace it with another. The search is case-sensitive.

Return value

If the scope attribute is set to one, returns a string with the first occurrence of the regular expression replaced by the value of substring.

If the scope attribute is set to all, returns a string with all occurrences of the regular expression replaced by the value of substring.

If the function finds no matches, it returns a copy of the string unchanged.

Category

String functions

Syntax

REReplace(string, reg_expression, substring [, scope ])

See also

REFind , Replace , ReplaceList , REReplaceNoCase

History

New in ColdFusion MX: this function supports the following special codes in a substring, to control case conversion:

  • \u - uppercase the next character
  • \l - lowercase the next character
  • \U - uppercase until \E
  • \L - lowercase until \E
  • \E - end \U or \L

As in ColdFusion 5, the characters \1, \2, and so on, are backreference codes. To include these literal characters in a substring, you must escape them, by inserting a backslash before them (for example, change "\u" to "\\u").

To include a backslash followed by a backreference or case conversion code, you must escape the backslash, by prefixing another backslash (for example, "\\\1").

For more information on new features, see REFind .

Parameters

Parameter
Description
string
A string or a variable that contains one. String within which to search.
reg_expression
Regular expression to replace. The search is case-sensitive.
substring
A string or a variable that contains one. Replaces reg_expression.
scope
  • one: replace the first occurrence (default)
  • all: replace all occurrences

Usage

For more information, see Developing ColdFusion MX Applications with CFML.

Example

<p>The REReplace function returns <i>string</i> with a regular expression replaced
with <i>substring</i> in the specified scope. Case-sensitive search.
<p>REReplace("CABARET","C|B","G","ALL"):
<cfoutput>#REReplace("CABARET","C|B","G","ALL")#</cfoutput>
<p>REReplace("CABARET","[A-Z]","G","ALL"):
<cfoutput>#REReplace("CABARET","[A-Z]","G","ALL")#</cfoutput>
<p>REReplace("I love jellies","jell(y|ies)","cookies"):
<cfoutput>#REReplace("I love jellies","jell(y|ies)","cookies")#
 </cfoutput>
<p>REReplace("I love jelly","jell(y|ies)","cookies"):
<cfoutput>#REReplace("I love jelly","jell(y|ies)","cookies")#</cfoutput>


REReplaceNoCase

Description

Uses a regular expression to search a string for a string pattern and replace it with another. The search is case-insensitive.

Return value

  • If scope = "one": returns a string with the first occurrence of the regular expression replaced by the value of substring.
  • If scope = "all": returns a string with all occurrences of the regular expression replaced by the value of substring.
  • If the function finds no matches: returns a copy of the string, unchanged.

Category

String functions

Syntax

REReplaceNoCase(string, reg_expression, substring [, scope ])

See also

REFind , REFindNoCase , Replace , ReplaceList

History

New in ColdFusion MX: this function inserts the following special characters in regular expression replacement strings, to control case conversion: \u, \U, \l, \L, and \E. If any of these strings is present in a ColdFusion 5 application, you must insert a backslash before it (for example, change "\u" to "\\u").

Parameters

Parameter
Description
string
A string or a variable that contains one.
reg_expression
Regular expression to replace. For more information, see Developing ColdFusion MX Applications with CFML.
substring
A string or a variable that contains one. Replaces reg_expression.
scope
  • one: Replace the first occurrence of the regular expression. Default.
  • all: Replace all occurrences of the regular expression.

Usage

To include a backslash character in a parameter of this function, you must precede it with another backslash, as an escape character.

Example

<p>The REReplaceNoCase function returns <i>string</i> with a regular
expression replaced with <i>substring</i> in the specified scope.
This is a case-insensitive search.
<p>REReplaceNoCase("cabaret","C|B","G","ALL"):
<cfoutput>#REReplaceNoCase("cabaret","C|B","G","ALL")#</cfoutput>
<p>REReplaceNoCase("cabaret","[A-Z]","G","ALL"):
<cfoutput>#REReplaceNoCase("cabaret","[A-Z]","G","ALL")#</cfoutput>
<p>REReplaceNoCase("I LOVE JELLIES","jell(y|ies)","cookies"):
<cfoutput>#REReplaceNoCase("I LOVE JELLIES","jell(y|ies)","cookies")#
</cfoutput>
<p>REReplaceNoCase("I LOVE JELLY","jell(y|ies)","cookies"):
<cfoutput>#REReplaceNoCase("I LOVE JELLY","jell(y|ies)","cookies")#
</cfoutput>


Reverse

Description

Reverses the order of items such as the characters in a string, the digits in a number, or the elements in an array.

Return value

A copy of string, with the characters in reverse order.

Category

String functions

Syntax

Reverse(string)

See also

Left , Mid , Right

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

You can call this function on a number with code such as the following:

<cfoutput>reverse(6*2) equals #reverse(6*2)#<cfoutput>

This code outputs the following:

reverse(6*2) equals 21

Example

<h3>Reverse Example</h3>

<p>Reverse returns your string with the positions of the characters reversed.
<cfif IsDefined("FORM.myString")>
   <cfif FORM.myString is not "">
      <p>Reverse returned:
      <cfoutput>#Reverse(FORM.myString)#</cfoutput>
   <cfelse>
      <p>Please enter a string to be reversed.
   </cfif>
</cfif>

<form action = "reverse.cfm">
<p>Enter a string to be reversed:
<input type = "Text" name = "MyString">
<p><input type = "Submit" name = "">
</form>


Right

Description

Gets a specified number of characters from a string, beginning at the right.

Return value

  • If the length of the string is greater than or equal to count, the rightmost count characters of the string
  • If count is greater than the length of the string, the whole string
  • If count is greater than 1, and the string is empty, an empty string

Category

String functions

Syntax

Right(string, count)

See also

Mid , Left , Reverse

Parameters

Parameter | Description
string | A string or a variable that contains one
count | A positive integer or a variable that contains one. Number of characters to return.

Example

<h3>Right Example</h3>
<cfif IsDefined("Form.MyText")>
<!--- if len is 0, then err --->
   <cfif Len(FORM.myText) is not 0>
      <cfif Len(FORM.myText) LTE FORM.RemoveChars>
      <p>Your string <cfoutput>#FORM.myText#</cfoutput>
      only has <cfoutput>#Len(FORM.myText)#</cfoutput>
      characters. You cannot output the <cfoutput>#FORM.removeChars#
     </cfoutput>
      rightmost characters of this string because it is not long enough
      <cfelse>
      <p>Your original string: <cfoutput>#FORM.myText#</cfoutput>
      <p>Your changed string, showing only the
<cfoutput>#FORM.removeChars#</cfoutput> rightmost characters:
      <cfoutput>#right(Form.myText, FORM.removeChars)#
       </cfoutput>
      </cfif>
   <cfelse>
   <p>Please enter a string
   </cfif>
</cfif>


RJustify

Description

Right justifies characters of a string.

Return value

A copy of a string, right-justified in the specified field length.

Category

Display and formatting functions, String functions

Syntax

RJustify(string, length)

See also

CJustify , LJustify

Parameters

Parameter | Description
string | A string enclosed in quotation marks, or a variable that contains one.
length | A positive integer or a variable that contains one. Length of field in which to justify string.

Example

<!--- This example shows how to use RJustify --->
<cfparam name = "jstring" default = "">

<cfif IsDefined("FORM.justifyString")>
   <cfset jstring = rjustify(FORM.justifyString, 35)>
</cfif>
<html>
<head>
<title>RJustify Example</title>
</head>
<body>
<h3>RJustify Function</h3>
<p>Enter a string. It will be right justified within the sample field

<form action = "rjustify.cfm">
<p><input type = "Text" value = "<cfoutput>#jString#</cfoutput>"
size = 35 name = "justifyString">

<p><input type = "Submit" name = ""> <input type = "reset">
</form>


Round

Description

Rounds a number to the closest integer.

Return value

An integer.

Category

Mathematical functions

Syntax

Round(number)

See also

Ceiling , Fix , Int

Parameters

Parameter | Description
number | Number to round

Example

<h3>Round Example</h3>
<p>This function rounds a number to the closest integer.
<ul>
   <li>Round(7.49) : <cfoutput>#Round(7.49)#</cfoutput>
   <li>Round(7.5) : <cfoutput>#Round(7.5)#</cfoutput>
   <li>Round(-10.775) : <cfoutput>#Round(-10.775)#</cfoutput>
   <li>Round(1.2345*100)/100 :
   <cfoutput>#Evaluate(Round(1.2345*100)/100)#</cfoutput>
</ul>


RTrim

Description

Removes spaces from the end of a string.

Return value

A copy of string, after removing trailing spaces.

Category

String functions

Syntax

RTrim(string)

See also

LTrim , Trim

Parameters

Parameter | Description
string | A string or a variable that contains one

Example

<h3>RTrim Example</h3>

<cfif IsDefined("FORM.myText")>
<cfoutput>
<pre>
Your string:   "#FORM.myText#"
Your string:   "#Rtrim(FORM.myText)#"
(right trimmed)
</pre>
</cfoutput>
</cfif>

<form action = "Rtrim.cfm" method="post">
<p>Enter some text. It will be modified by Rtrim to remove spaces from the right.
<p><input type = "Text" name = "myText" value = "TEST   ">

<p><input type = "Submit" name = "">
</form>


Second

Description

Extracts the ordinal for the second from a date/time object.

Return value

An integer in the range 0–59.

Category

Date and time functions

Syntax

Second(date)

See also

DatePart , Hash , Minute

Parameters

Parameter | Description
date | A date/time object

Usage

When passing a date/time object as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Example

<!--- This example shows the use of Hour, Minute, and Second --->
<h3>Second Example</h3>
<cfoutput>
The time is currently #TimeFormat(Now())#.
We are in hour #Hour(Now())#, Minute #Minute(Now())#
and Second #Second(Now())# of the day.
</cfoutput>


SetEncoding

Description

Sets the character encoding of Form and URL scope variable values; used when the character set of the input to a form, or the character set of a URL, is not in Latin-1 encoding (ISO-8859-1).

Return value

None

Category

Display and formatting functions, System functions

Syntax

SetEncoding(scope_name,charset)

See also

cfcontent, cfprocessingdirective, URLDecode, URLEncodedFormat

Parameters

Parameter
Description
scope_name
  • url
  • form
charset
A Java character set name for the file contents. The following values are typically used:
  • EUC-JP
  • EUC-K
  • ISO-8859-1
  • SHIFT-JIS
  • UTF-8 (Default)
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Usage

Use this tag when the character set of the input to a form or the character set of a URL is not in Latin-1 encoding. For example, Traditional Chinese characters are in Big5 encoding. Before getting URL or FORM parameters, call this function (typically, in the application.cfml page) to set the encoding and avoid getting incorrect parameter values.

For more information, see: http://www.iana.org/assignments/character-sets.

The following example shows how you could process form data such as the following:

<form action='process.cfm' method='get'>
<input name='xxx' type='text'>
<input name='yyy' type='text'>
</form>

Example

<cfoutput>
   setEncoding("url", "big5");
   writeoutput(URL.xxx);
   writeoutput(URL.yyy);
</cfoutput>


SetLocale

Description

Sets a country/language locale option for a ColdFusion application user; the setting persists for the current ColdFusion application session. The locale value encapsulates a set of attributes that determine the default display format of date, time, number, and currency values, according to language and regional conventions.

For information about determining the locale value, see GetLocale .

Return value

An element from the list of locales that ColdFusion supports, as a string.

Category

International functions, System functions

Syntax

SetLocale(new_locale)

See also

GetHttpTimeString , GetLocale

History

New in ColdFusion MX:

  • This function might return a different value than in earlier releases. This function uses Java standard locale determination and formatting rules on all platforms.
  • The Spanish (Mexican) locale option is deprecated. Do not use it in new applications. It might not work, and it might cause an error, in later releases. (The Spanish (Modern) option now maps to Spanish (Standard).)

Parameters

Parameter | Description
new_locale | The name of a locale; for example, "en_US" (English, United States)

Usage

This function uses Java standard locale formatting rules on all platforms.

A locale value can be explicitly set in the following ways:

  • From the command line; for example: java -Duser.language=de -Duser.region=DE.
  • In JSP code; for example: response.setLocale ( new Locale( "de", "DE") )
  • With the SetLocale function; for example: SetLocale ("German (Standard)"

The locale value persistence and usage hierarchy is as follows:

  • When the locale is set explicitly, its value persists until the ColdFusion server is stopped. ColdFusion accesses this value.
  • The ColdFusion Server operating system default locale value persists permanently. If the value has not been explicitly set and stored in the JSP request object, ColdFusion uses this value.
  • If the operating system does not have a default value or the value is not one that ColdFusion supports, ColdFusion uses the value English (US).

ColdFusion supports the following locale options. You can use either the ColdFusion locale name or the Java standard locale string.

ColdFusion locale name | Java standard locale string
Chinese (China) |
Chinese (Hong Kong) |
Chinese (Taiwan) |
Dutch (Belgian) | nl_be
Dutch (Standard) | nl_NL
English (Australian) | en_AU
English (Canadian) | en_CA
English (New Zealand) | en_NZ
English (UK) | en_GB
English (US) | en_US
French (Belgian) | fr_BE
French (Canadian) | fr_CA
French (Standard) | fr_FR
French (Swiss) | fr_CH
German (Austrian) | de_AT
German (Standard) | de_DE
German (Swiss) | de_CH
Italian (Standard) | it_IT
Italian (Swiss) | it_CH
Japanese | ja_JP
Korean | ko_KR
Norwegian (Bokmal) | no_NO
Norwegian (Nynorsk) | no_NO_nynorsk
Portuguese (Brazilian) | pt_BR
Portuguese (Standard) | pt_PT
Spanish (Modern) | es_ES
Spanish (Standard) | es_ES
Swedish | sv_SE

Note: ColdFusion uses the Spanish (Standard) formats for Spanish (Modern) and Spanish (Standard).

This function can restore a locale setting by referencing the session variable that stores a locale, as follows:

<cfset oldlocale = SetLocale("localename")>

Note: The variable server.ColdFusion.SupportedLocales is initialized at startup with a comma-delimited list of the locales that ColdFusion and the operating system support. If it is called with a locale that is not in the list, SetLocale fails.

Example

<h3>SetLocale Example</h3>
<p>SetLocale sets the locale to the specified new locale for the current session.
<p>A locale encapsulates the set of attributes that govern the display and
formatting of date, time, number, and currency values.
<p>The locale for this system is <cfoutput>#GetLocale()#</cfoutput>
<p><cfoutput><I>the old locale was #SetLocale("English (UK)")#</I>
<p>The locale is now #GetLocale()#</cfoutput>


SetProfileString

Description

Sets the value of a profile entry in an initialization file.

Return value

An empty string, upon successful execution; otherwise, an error message.

Category

System functions

Syntax

SetProfileString(iniPath, section, entry, value)

See also

GetProfileSections , GetProfileString , SetProfileString

Parameters

Parameter | Description
iniPath | Absolute path of initialization file
section | Section of the initialization file in which the entry is to be set
entry | Name of the entry to set
value | Value to which to set the entry

Example

<h3>SetProfileString Example</h3>
This example uses SetProfileString to set the timeout value in an
initialization file. Enter the full path of your initialization
file, specify the timeout value, and submit the form.
<!--- This section checks whether the form was submitted. If so, this
section sets the initialization path and timeout value to the
path and timeout value specified in the form --->
<cfif Isdefined("Form.Submit")>

   <cfset IniPath = FORM.iniPath>
   <cfset Section = "boot loader">
   <cfset MyTimeout = FORM.MyTimeout>
   <cfset timeout = GetProfileString(IniPath, Section, "timeout")>

   <cfif timeout Is Not MyTimeout>
    <cfif MyTimeout Greater Than 0>
       <hr size = "2" color = "#0000A0">
      <p>Setting the timeout value to <cfoutput>#MyTimeout#</cfoutput>
      </p>
         <cfset code = SetProfileString(IniPath,
            Section, "timeout", MyTimeout)>
      <p>Value returned from SetProfileString:
            <cfoutput>#code#</cfoutput></p>
      <cfelse>
         <hr size = "2" color = "red">
         <p>Timeout value should be greater than zero in order to
            provide time for user response.</p>
         <hr size = "2" color = "red">
      </cfif>
   <cfelse>
      <p>The timeout value in your initialization file is already
         <cfoutput>#MyTimeout#</cfoutput>.</p>
   </cfif>

   <cfset timeout = GetProfileString(IniPath, Section, "timeout")>
   <cfset default = GetProfileString(IniPath, Section, "default")>

   <h4>Boot Loader</h4>
   <p>Timeout is set to: <cfoutput>#timeout#</cfoutput>.</p>
   <p>Default directory is: <cfoutput>#default#</cfoutput>.</p>

</cfif>

<form action = "setprofilestring.cfm">
<hr size = "2" color = "#0000A0">
<table cellspacing = "2" cellpadding = "2" border = "0">
<tr>
  <td>Full Path of Init File</td>
  <td><input type = "Text" name = "IniPath"
            value = "C:\myboot.ini"></td>
</tr>
<tr>
  <td>Timeout</td>
  <td><input type = "Text" name = "MyTimeout" value = "30"></td>
</tr>
<tr>
  <td><input type = "Submit" name = "Submit" value = "Submit"></td>
  <td></td>
</tr>
</table>
</form>


SetVariable

Description

This function is no longer required in well-formed ColdFusion pages.

Sets a variable in the name parameter to the value of the value parameter.

Return value

The new value of the variable.

Category

Dynamic evaluation functions

Syntax

SetVariable(name, value)

See also

DE , Evaluate , IIf

Parameters

Parameter | Description
name | Variable name
value | A string, the name of a string, or a number

Usage

Before this function is called, the client variable must exist, and the cfapplication tag ClientManagement attribute must be set to "Yes".

Note: If you concatenate string elements to form the name parameter, you can improve performance using the cfset tag, instead.

For example:

      <cfset "myVar#i#" = myVal>

is faster than:

      SetVariable("myVar" & i, myVal)

For more information, see Developing ColdFusion MX Applications with CFML.

Example

<h3>SetVariable Example</h3>

<cfif IsDefined("FORM.myVariable")>
<!--- strip out url, client., cgi., session., caller. --->
<!--- This example only lets you set form variables --->
<cfset myName = ReplaceList(FORM.myVariable,
 "url,client,cgi,session,caller", "FORM,FORM,FORM,FORM,FORM")>

<cfset temp = SetVariable(myName, FORM.myValue)>
<cfset varName = myName>
<cfset varNameValue = Evaluate(myName)>
<cfoutput>
   <p>Your variable, #varName#
   <p>The value of #varName# is #varNameValue#
</cfoutput>
</cfif>


Sgn

Description

Determines the sign of a number.

Return value

  • 1, if number is positive.
  • 0, if number is 0.
  • -1, if number is negative.

Category

Mathematical functions

Syntax

Sgn(number)

See also

Abs

Parameters

Parameter | Description
number | A number

Example

<h3>Sgn Example</h3>
<p>Sgn determines the sign of a number. Returns 1 if number is positive;
0 if number is 0; -1 if number is negative.
<p>Sgn(14): <cfoutput>#Sgn(14)#</cfoutput>
<p>Sgn(21-21): <cfoutput>#Sgn(21-21)#</cfoutput>
<p>Sgn(-0.007): <cfoutput>#Sgn(-0.007)#</cfoutput>


Sin

Description

Calculates the sine of an angle.

Return value

A number; the sine of the angle number.

Category

Mathematical functions

Syntax

Sin(number)

See also

ASin , Atn , Cos , Pi , Tan

Parameters

Parameter | Description
number | Angle, in radians. To convert an angle from degrees to radians, use the PI function to multiply the degrees by pi/180.

Example

<h3>Sin Example</h3>

<!--- output its Sin value --->
<cfif IsDefined("FORM.SinNum")>
   <cfif IsNumeric(FORM.SinNum)>
      Sin(<cfoutput>#FORM.SinNum#</cfoutput>) =
       <cfoutput>#Sin(FORM.sinNum)# Degrees =
        #Evaluate(Sin(FORM.sinNum) * PI()/180)# Radians
       </cfoutput>
   <cfelse>
<!--- if it is empty, output an error message --->
      <h4>Please enter an angle for which you want the Sine value</h4>
   </cfif>
</cfif>

<form action = "sin.cfm">
<p>Type in a number to get its sine in Radians and Degrees
<br><input type = "Text" name = "sinNum" size = "25">
<p><input type = "Submit" name = ""> <input type = "RESET">
</form>


SpanExcluding

Description

Gets characters from a string, from the beginning to a character that is in a specified set of characters. The search is case-sensitive.

Return value

A string; characters from string, from the beginning to a character that is in set.

Category

String functions

Syntax

SpanExcluding(string, set)

See also

GetToken , SpanIncluding

Parameters

Parameter | Description
string | A string or a variable that contains one
set | A string or a variable that contains one. Must contain one or more characters

Example

<h3>SpanExcluding Example</h3>

<cfif IsDefined("FORM.myString")>
<p>Your string was <cfoutput>#FORM.myString#</cfoutput>
<p>Your set of characters was <cfoutput>#FORM.mySet#</cfoutput>
<p>Your string up until one of the characters in the set is:
<cfoutput>#SpanExcluding(FORM.myString, FORM.mySet)#</cfoutput>
</cfif>

<p>Returns all characters from string from beginning to a character
from the set of characters. The search is case-sensitive.

<form action = "spanexcluding.cfm">
<p>Enter a string:
<br><input type = "Text" name = "myString" value = "Hey, you!">
<p>And a set of characters:
<br><input type = "Text" name = "mySet" value = "Ey">
<br><input type = "Submit" name = "">
</form>


SpanIncluding

Description

Gets characters from a string, from the beginning to a character that is not in a specified set of characters. The search is case-sensitive.

Return value

A string; characters from string, from the beginning to a character that is not in set.

Category

String functions

Syntax

SpanIncluding(string, set)

See also

GetToken , SpanExcluding

Parameters

Parameter | Description
string | A string or a variable that contains the search string.
set | A string or a variable that contains a set of characters. Must contain one or more characters

Example

<h3>SpanIncluding Example</h3>
<cfif IsDefined("FORM.myString")>
<p>Your string was <cfoutput>#FORM.myString#</cfoutput>
<p>Your set of characters was <cfoutput>#FORM.mySet#</cfoutput>
<p>Your string, until the characters in the set have been found, is:
<cfoutput>#SpanIncluding(FORM.myString, FORM.mySet)#</cfoutput>
</cfif>

<p>Returns characters of a string, from beginning to a character
that is not in set. The search is case-sensitive.

<form action = "spanincluding.cfm" method="post">
<p>Enter a string:
<br><input type = "Text" name = "myString" value = "Hey, you!">
<p>And a set of characters:
<br><input type = "Text" name = "mySet" value = "ey,H">
<br><input type = "Submit" name = "">
</form>


Sqr

Description

Calculates the square root of a number.

Return value

Number; square root of number.

Category

Mathematical functions

Syntax

Sqr(number)

See also

Abs

Parameters

Parameter | Description
number | A positive integer or a variable that contains one. Number whose square root to get.

Usage

The value in number must be greater than or equal to 0.

Example

<h3>Sqr Example</h3>

<p>Returns the square root of a positive number.

<p>Sqr(2): <cfoutput>#Sqr(2)#</cfoutput>
<p>Sqr(Abs(-144)): <cfoutput>#Sqr(Abs(-144))#</cfoutput>
<p>Sqr(25^2): <cfoutput>#Sqr(25^2)#</cfoutput>


StripCR

Description

Deletes return characters from a string.

Return value

A copy of string, after removing return characters.

Category

Display and formatting functions, Other functions, String functions

Syntax

StripCR(string)

See also

ParagraphFormat

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

Useful for preformatted (between <pre> and </pre> tags) HTML display of data entered in textarea fields.

Example

<h3>StripCR Example</h3>

<p>Function StripCR is useful for preformatted HTML display of data
(PRE) entered in textarea fields.
<cfif isdefined("Form.myTextArea")>

<pre>
<cfoutput>#StripCR(Form.myTextArea)#</cfoutput>
</pre>
</cfif>
<!--- use #Chr(10)##Chr(13)# to simulate line feed/carriage return combination --->
<form action = "stripcr.cfm">
<textarea name = "MyTextArea" cols = "35" rows = 8>
This is sample text and you see how it scrolls
   <cfoutput>#Chr(10)##Chr(13)#</cfoutput>
From one line
   <cfoutput>#Chr(10)##Chr(13)##Chr(10)##Chr(13)#</cfoutput>
to the next
</textarea>
<input type = "Submit" name = "Show me the HTML version">
</form>


StructAppend

Description

Appends one structure to another.

Return value

True, upon successful completion; False, otherwise.

Category

Structure functions

Syntax

StructAppend(struct1, struct2, overwriteFlag)

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter
Description
struct1
Structure to append.
struct2
Structure that contains the data to append to struct1
overwriteFlag
  • Yes: values in struct2 overwrite corresponding values in struct1. Default.
  • No

Usage

This function appends the fields and values of struct2 to struct1; struct2 is not modified. If struct1 already contains a field of struct2, overwriteFlag determines whether the value in struct2 overwrites it.

A structure’s keys are unordered.

Example

<html>
<body>
<!---- Create a Name structure --->
<cfset nameCLK=StructNew()>
<cfset nameCLK.first="Chris">
<cfset nameCLK.middle="Lloyd">
<cfset nameCLK.last="Gilson">
<!--- Create an address struct --->
<cfset addrCLK=StructNew()>
<cfset addrCLK.street="17 Gigantic Rd">
<cfset addrCLK.city="Watertown">
<cfset addrCLK.state="MA">
<cfset addrCLK.zip="02472">
<!---- Create a Person structure --->
<cfset personCLK=StructNew()>
<cfset personCLK.name=#nameCLK#>
<cfset personCLK.addr=#addrCLK#>
<!--- Display the contents of the person struct before the Append --->
<p>
The person struct <b>before</b> the Append call:<br>
<cfloop collection=#personCLK# item="myItem">
<cfoutput>
#myItem#<br>
</cfoutput>
</cfloop>
<!--- Merge the Name struct into the top-level person struct --->
<cfset bSuccess = StructAppend( personCLK, addrCLK )>

<!--- Display the contents of the person struct, after the Append --->
<p>
The person struct <b>after</b> the Append call:<br>
<cfloop collection=#personCLK# item="myItem">
   <cfoutput>
      #myItem#<br>
   </cfoutput>
</cfloop>


StructClear

Description

Removes all data from a structure.

Return value

True, on successful execution; False, otherwise.

Category

Structure functions

Syntax

StructClear(structure)

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
structure | Structure to clear

Usage

Do not call this function on a session variable. For more information, see TechNote 14143, "ColdFusion 4.5 and the StructClear(Session) function," at . (The article applies to ColdFusion 4.5, 5.x, and ColdFusion MX.)

Example

<!--- Shows StructClear function. Calls cf_addemployee custom tag which
   uses the addemployee.cfm file. --->
<body>
<h1>Add New Employees</h1>
<!--- Establish parms for first time through --->
<cfparam name = "Form.firstname" default = "">
<cfparam name = "Form.lastname" default = "">
<cfparam name = "Form.email" default = "">
<cfparam name = "Form.phone" default = "">
<cfparam name = "Form.department" default = "">
<cfif form.firstname eq "">
 <p>Please fill out the form.
<cfelse>
 <cfoutput>
  <cfscript>
   employee = StructNew();
   StructInsert(employee, "firstname", Form.firstname);
   StructInsert(employee, "lastname", Form.lastname);
   StructInsert(employee, "email", Form.email);
   StructInsert(employee, "phone", Form.phone);
   StructInsert(employee, "department", Form.department);
  </cfscript>
 </cfoutput>
<!--- Call the custom tag that adds employees --->
 <cf_addemployee empinfo = "#employee#">
 <cfscript>StructClear(employee);</cfscript>
 </cfif>


StructCopy

Description

Copies a structure. Copies top-level keys, values, and arrays in the structure by value; copies nested structures by reference.

Return value

A copy of a structure, with the same keys and values; if structure does not exist, throws an exception.

Category

Structure functions

Syntax

StructCopy(structure)

See also

Structure functions

Parameters

Parameter | Description
structure | Structure to copy

Usage

The following code shows how this function copies a structure that contains a string field, a number field, and a two-dimensional array at the top level:

<cfoutput>
   <cfset assignedCopy = StructNew()>
  <cfset assignedCopy.string = #struct.string#>
   <cfset assignedCopy.number = #struct.number#>
   <cfset assignedCopy.array = ArrayNew(2)>
   <cfset assignedCopy.array[1][1] = #struct.array[1][1]#>
   <cfset assignedCopy.array[1][2] = #sruct.array[1][2]#>
</cfoutput>

The following code shows how StructCopy copies a nested structure:

<cfoutput>
  <cfset assignedCopy.nestedStruct = struct.nestedStruct>
</cfoutput>

To copy a structure entirely by value, use Duplicate.

The following table shows how variables are assigned.

Variable type | Assigned by
structure.any_simple_value Boolean Binary Base64 | Value
structure.array | Value
structure.nested_structure | Reference
structure.object | Reference
structure.query | Reference

Example

<!--- This code shows assignment by-value and by-reference. --->
// This script creates a structure that StructCopy copies by value. <br>
<cfscript>
   // Create elements.
   s = StructNew();
   s.array = ArrayNew(2);

   // Assign simple values to original top-level structure fields.
   s.number = 99;
   s.string = "hello tommy";

   // Assign values to original top-level array.
   s.array[1][1] = "one one";
   s.array[1][2] = "one two";
</cfscript>

<!--- Output original structure --->
<hr>
<b>Original Values</b><br>
<cfoutput>
   // Simple values <br>
   s.number = #s.number#<br>
   s.string = #s.string#<br>
   // Array value <br>
   s.array[1][1] = #s.array[1][1]#<br>
   s.array[1][2] = #s.array[1][2]#<br>
</cfoutput>

// Copy this structure to a new structure. <br>
<cfset copied = StructCopy(s)>

<cfscript>
// Change the values of the original structure. <br>
   s.number = 100;
   s.string = "hello tommy (modified)";
   s.array[1][1] = "one one (modified)";
   s.array[1][2] = "one two (modified)";
</cfscript>
<hr>
<b>Modified Original Values</b><br>
<cfoutput>
   // Simple values <br>
   s.number = #s.number#<br>
   s.string = #s.string#<br>
   // Array value <br>
   s.array[1][1] = #s.array[1][1]#<br>
   s.array[1][2] = #s.array[1][2]#<br>
</cfoutput>
<hr>
<b>Copied structure values should be the same as the original.</b><br>
<cfoutput>
   // Simple values <br>
   copied.number = #copied.number#<br>
   copied.string = #copied.string#<br>
   // Array value <br>
   copied.array[1][1] = #copied.array[1][1]#<br>
   copied.array[1][2] = #copied.array[1][2]#<br>
</cfoutput>

// This script creates a structure that StructCopy copies by reference.
<cfscript>
   // Create elements.
   s = StructNew();
   s.nested = StructNew();
   s.nested.array = ArrayNew(2);
   // Assign simple values to nested structure fields.
   s.nested.number = 99;
   s.nested.string = "hello tommy";
   // Assign values to nested array.
   s.nested.array[1][1] = "one one";
   s.nested.array[1][2] = "one two";
</cfscript>

<!--- Output original structure --->
<hr>
<b>Original Values</b><br>
<cfoutput>
   // Simple values <br>
   s.nested.number = #s.nested.number#<br>
   s.nested.string = #s.nested.string#<br>

   // Array values <br>
   s.nested.array[1][1] = #s.nested.array[1][1]#<br>
   s.nested.array[1][2] = #s.nested.array[1][2]#<br>
</cfoutput>

// Use StructCopy to copy this structure to a new structure. <br>
<cfset copied = StructCopy(s)>
// Use Duplicate to clone this structure to a new structure. <br>
<cfset duplicated = Duplicate(s)>

<cfscript>
// Change the values of the original structure.
   s.nested.number = 100;
   s.nested.string = "hello tommy (modified)";
   s.nested.array[1][1] = "one one (modified)";
   s.nested.array[1][2] = "one two (modified)";
</cfscript>
<hr>
<b>Modified Original Values</b><br>
<cfoutput>
   // Simple values <br>
   s.nested.number = #s.nested.number#<br>
   s.nested.string = #s.nested.string#<br>

   // Array value <br>
   s.nested.array[1][1] = #s.nested.array[1][1]#<br>
   s.nested.array[1][2] = #s.nested.array[1][2]#<br>
</cfoutput>

<hr>
<b>Copied structure values should reflect changes to original.</b><br>
<cfoutput>
   // Simple values <br>
   copied.nested.number = #copied.nested.number#<br>
   copied.nested.string = #copied.nested.string#<br>
   // Array values <br>
   copied.nested.array[1][1] = #copied.nested.array[1][1]#<br>
   copied.nested.array[1][2] = #copied.nested.array[1][2]#<br>
</cfoutput>

<hr>
<b>Duplicated structure values should remain unchanged.</b><br>
<cfoutput>
   // Simple values <br>
   duplicated.nested.number = #duplicated.nested.number#<br>
   duplicated.nested.string = #duplicated.nested.string#<br>
   // Array value <br>
   duplicated.nested.array[1][1] = #duplicated.nested.array[1][1]#<br>
   duplicated.nested.array[1][2] = #duplicated.nested.array[1][2]#<br>
</cfoutput>


StructCount

Description

Counts the keys in a structure.

Return value

A number; if structure does not exist, throws an exception.

Category

Structure functions

See also

Structure functions

Syntax

StructCount(structure)

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
structure | Structure to access

Example

<!--- This view-only example shows use of StructCount. --->
<p>This file is similar to addemployee.cfm, which is called by
StructNew, StructClear, and StructDelete. To test, copy
StructCount function to appropriate place in addemployee.cfm.
<!---
<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif StructIsEmpty(attributes.EMPINFO)>
    <cfoutput>Error. No employee data was passed.</cfoutput>
     <cfexit method = "ExitTag">
   <cfelse>
    <cfquery name = "AddEmployee" datasource = "cfsnippets">
     INSERT INTO Employees
       (FirstName, LastName, Email, Phone, Department)
      VALUES
       <cfoutput>
        (
         ‘#StructFind(attributes.EMPINFO, "firstname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "lastname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "email")#’ ,
         ‘#StructFind(attributes.EMPINFO, "phone")#’ ,
         ‘#StructFind(attributes.EMPINFO, "department")#’
         )
       </cfoutput>
     </cfquery>
   </cfif>
   <cfoutput><hr>Employee Add Complete
     <p>#StructCount(attributes.EMPINFO)# columns added.</cfoutput>
  </cfcase>
</cfswitch> --->


StructDelete

Description

Removes an element from a structure.

Return value

A structure, after removing the element.

Category

Structure functions

Syntax

StructDelete(structure, key [, indicatenotexisting ])

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter
Description
structure
Structure or a variable that contains one. Contains element to remove
key
Element to remove
indicatenotexisting
  • True: returns Yes if key exists; No if it does not.
  • False: returns Yes regardless of whether key exists. Default.

Example

<h3>StructDelete Function</h3>
<p>This example uses the StructInsert and StructDelete functions.
<!--- Establish parms for first time through --->
<cfparam name = "firstname" default = "Mary">
<cfparam name = "lastname" default = "Sante">
<cfparam name = "email" default = "msante@allaire.com">
<cfparam name = "phone" default = "777-777-7777">
<cfparam name = "department" default = "Documentation">

 <cfif IsDefined("FORM.Delete")>
 <cfoutput>
 Field to be deleted: #form.field#
 </cfoutput>
 <p>
  <CFScript>
   employee = StructNew();
   StructInsert(employee, "firstname", firstname);
   StructInsert(employee, "lastname", lastname);
   StructInsert(employee, "email", email);
   StructInsert(employee, "phone", phone);
   StructInsert(employee, "department", department);
  </CFScript>
    <cfoutput>
     employee is a structure: #IsStruct(employee)#
    </cfoutput>
    <cfset rc = StructDelete(employee, "#form.field#", "True")>
    <cfoutput>
   <p>Did I delete the field "#form.field#"? The code indicates: #rc#
    </p>
   </cfoutput>
</cfif>
<cfif NOT IsDefined("FORM.Delete")>
<form action = "structdelete.cfm">
      <p>Select the field to be deleted:&nbsp;
      <select name = "field">
      <option value = "firstname">first name
      <option value = "lastname">last name
      <option value = "email">email
      <option value = "phone">phone
      <option value = "department">department
      </select>
      <input type = "submit" name = "Delete" value = "Delete">
    </form>
</cfif>


StructFind

Description

Determines the value associated with a key in a structure.

Return value

The value associated with a key in a structure; if structure does not exist, throws an exception.

Category

Structure functions

Syntax

StructFind(structure, key)

See also

Structure functions

Parameters

Parameter | Description
structure | Structure that contains the value to return
key | Key whose value to return

Usage

A structure’s keys are unordered.

Example

<!--- This view-only example shows the use of StructFind. --->
<p>This file is identical to addemployee.cfm, which is called by StructNew,
StructClear, and StructDelete. It adds employees. Employee information
is passed through the employee structure (EMPINFO attribute). In UNIX,
you must also add the Emp_ID.
<!---
<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif StructIsEmpty(attributes.EMPINFO)>
    <cfoutput>Error. No employee data was passed.</cfoutput>
     <cfexit method = "ExitTag">
   <cfelse>
     <cfquery name = "AddEmployee" datasource = "cfsnippets">
     INSERT INTO Employees (FirstName, LastName, Email, Phone, Department)
      VALUES
       <cfoutput>
        (
         ‘#StructFind(attributes.EMPINFO, "firstname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "lastname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "email")#’ ,
         ‘#StructFind(attributes.EMPINFO, "phone")#’ ,
         ‘#StructFind(attributes.EMPINFO, "department")#’ )
       </cfoutput>
    </cfquery>
   </cfif>
   <cfoutput><hr>Employee Add Complete</cfoutput>
  </cfcase>
</cfswitch> --->


StructFindKey

Description

Searches recursively through a substructure of nested arrays, structures, and other elements, for structures whose values match the search key in the value parameter.

Return value

An array that contains structures with values that match value.

Category

Structure functions

Syntax

StructFindKey(top, value, scope)

See also

Structure functions

Parameters

Parameter
Description
top
ColdFusion object (structure or array) from which to start search. This attribute requires an object, not a name of an object.
value
String or a variable that contains one for which to search.
scope
  • one: returns one matching key. Default.
  • all: returns all matching keys

Usage

Returns an array that includes one structure for each of the specified values it finds. The fields of each of these structures are:

  • Value: value held in the found key
  • Path: string that can be used to reach the found key
  • Owner: parent object that contains the found key

A structure’s keys are unordered.

Example

<cfset aResults = StructFindKey( #request#, "bass" )>


StructFindValue

Description

Searches recursively through a substructure of nested arrays, structures, and other elements for structures with values that match the search key in the value parameter.

Return value

An array that contains structures with values that match the search key value. If none are found, returns an array of size 0.

Category

Structure functions

Syntax

StructFindValue( top, value [, scope])

See also

Structure functions

Parameters

Parameter
Description
top
ColdFusion object (a structure or an array) from which to start search. This attribute requires an object, not a name of an object.
value
String or a variable that contains one for which to search.
The type must be a simple object. Arrays and structures are not supported.
scope
  • one: function returns one matching key (default)
  • all: function returns all matching keys

Usage

The fields of each structure in the returned array are:

  • Key: name of the key in which the value was found
  • Path: string which could be used to reach the found key
  • Owner: parent object that contains the found key

A structure’s keys are unordered.

Example

<cfset aResults = StructFindValue( #request#, "235" )>


StructGet

Description

Gets a structure(s) from a specified path.

Return value

An alias to the variable in the PathDesired parameter. If necessary, StructGet creates structures or arrays to make PathDesired a valid variable "path."

Category

Structure functions

Syntax

StructGet(pathDesired)

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

New in ColdFusion MX: if there is no structure or array present in pathDesired, this function creates structures or arrays to make PathDesired a valid variable "path."

Parameters

Parameter | Description
pathDesired | Pathname of variable that contains structure or array from which ColdFusion retrieves structure.

Usage

You can inadvertently create invalid structures using this function. For example, if array notation is used to expand an existing array, the specified new element is created, regardless of the type currently held in the array.

Example

<!--- GetStruct() test --->
<cfset test = StructGet( "dog.myscope.test" )>
<cfset test.foo = 1>
<cfif NOT IsDefined("dog")>
   Dog is not defined<br>
</cfif>
<cfif NOT IsDefined("dog.myscope")>
   Dog.Myscope is not definded<br>
</cfif>
<cfif NOT Isdefined("dog.myscope.test")>
   Dog.Myscope.Test is not defined<br>
</cfif>
<cfif NOT Isdefined("dog.myscope.test.foo")>
   Dog.Myscope.Test.Foo is not defined<br>
</cfif>
<cfoutput>
   #dog.myscope.test.foo#<br>
</cfoutput>
<cfset test = StructGet( "request.myscope[1].test" )>
<cfset test.foo = 2>
<cfoutput>
   #request.myscope[1].test.foo#<br>
</cfoutput>
<cfset test = StructGet( "request.myscope[1].test[2]" )>
<cfset test.foo = 3>
<cfoutput>
   #request.myscope[1].test[2].foo#<br>
</cfoutput>


StructInsert

Description

Inserts a key-value pair into a structure.

Return value

True, upon successful completion. If structure does not exist, or if key exists and allowoverwrite = "False", ColdFusion throws an exception.

Category

Structure functions

Syntax

StructInsert(structure, key, value [, allowoverwrite ])

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
structure | Structure to contain the new key-value pair.
key | Key that contains the inserted value.
value | Value to add.
allowoverwrite | Optional. Whether to allow overwriting a key. Default: False.

Usage

A structure’s keys are unordered.

Example

<h1>Add New Employees</h1>
<!--- Establish parms for first time through --->
<cfparam name = "FORM.firstname" default = "">
<cfparam name = "FORM.lastname" default = "">
<cfparam name = "FORM.email" default = "">
<cfparam name = "FORM.phone" default = "">
<cfparam name = "FORM.department" default = "">

<cfif FORM.firstname EQ "">
 <p>Please fill out the form.
<cfelse>
 <cfoutput>
  <CFScript>
   employee = StructNew();
   StructInsert(employee, "firstname", FORM.firstname);
   StructInsert(employee, "lastname", FORM.lastname);
   StructInsert(employee, "email", FORM.email);
   StructInsert(employee, "phone", FORM.phone);
   StructInsert(employee, "department", FORM.department);
 </CFScript>

 <p>First name is #StructFind(employee, "firstname")#</p>
 <p>Last name is #StructFind(employee, "lastname")#</p>
 <p>EMail is #StructFind(employee, "email")#</p>
 <p>Phone is #StructFind(employee, "phone")#</p>
 <p>Department is #StructFind(employee, "department")#</p>
 </cfoutput>

 <!--- Call the custom tag that adds employees --->
 <CF_ADDEMPLOYEE EMPINFO = "#employee#">
</cfif>

<Hr>
<form action = "structinsert.cfm">
   <p>First Name:&nbsp;
   <input name = "firstname" type = "text" hspace = "30" maxlength = "30">
   <p>Last Name:&nbsp;
   <input name = "lastname" type = "text" hspace = "30" maxlength = "30">
   <p>EMail:&nbsp;
   <input name = "email" type = "text" hspace = "30" maxlength = "30">
   <p>Phone:&nbsp;
   <input name = "phone" type = "text" hspace = "20" maxlength = "20">
   <p>Department:&nbsp;
   <input name = "department" type = "text" hspace = "30" maxlength = "30">
   <p>
   <input type = "submit" value = "OK">
</form>


StructIsEmpty

Description

Determines whether a structure contains data.

Return value

True, if structure is empty; if structure does not exist, ColdFusion throws an exception.

Category

Decision functions, Structure functions

Syntax

StructIsEmpty(structure)

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
structure | Structure to test

Example

<!--- This example illustrates use of StructIsEmpty. --->
<p>This file is identical to addemployee.cfm, which is called by StructNew,
StructClear, and StructDelete. It adds employees. Employee information
is passed through employee structure (EMPINFO attribute). In UNIX, you
must also add the Emp_ID.
<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif StructIsEmpty(attributes.EMPINFO)>
    <cfoutput>Error. No employee data was passed.</cfoutput>
     <cfexit method = "ExitTag">
   <cfelse>
    <!--- Add the employee; In UNIX, you must also add the Emp_ID --->
     <cfquery name = "AddEmployee" datasource = "cfsnippets">
     INSERT INTO Employees
       (FirstName, LastName, Email, Phone, Department)
      VALUES
       <cfoutput>
        (
         ‘#StructFind(attributes.EMPINFO, "firstname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "lastname")#’ ,
         ‘#StructFind(attributes.EMPINFO, "email")#’ ,
         ‘#StructFind(attributes.EMPINFO, "phone")#’ ,
         ‘#StructFind(attributes.EMPINFO, "department")#’
         )
       </cfoutput>
    </cfquery>
   </cfif>
   <cfoutput><hr>Employee Add Complete</cfoutput>
  </cfcase>
</cfswitch>


StructKeyArray

Description

Finds the keys in a ColdFusion structure.

Return value

An array of keys; if structure does not exist, ColdFusion throws an exception.

Category

Structure functions

Syntax

StructKeyArray(structure)

See also

Structure functions

Parameters

Parameter | Description
structure | Structure from which to extract a list of keys

Usage

A structure’s keys are unordered.

Example

<!--- Shows StructKeyArray function to copy keys from a structure to an array.
Uses StructNew to create structure and fills its fields with the
information the user enters in the form fields. --->
<h3>StructKeyArray Example</h3>
<h3>Extracting the Keys from the Employee Structure</h3>
<!-- Create structure. Check whether Submit was pressed. If so, define fields
in employee structure with user entries on form. ----->
<cfset employee = StructNew()>
<cfif Isdefined("Form.Submit")>
   <cfif Form.Submit is "OK">
      <cfset employee.firstname = FORM.firstname>
      <cfset employee.lastname = FORM.lastname>
      <cfset employee.email = FORM.email>
      <cfset employee.phone = FORM.phone>
      <cfset employee.company = FORM.company>
   <cfelseIf Form.Submit is "Clear">
      <cfset rc = StructClear(employee)>
   </cfif>
</cfif>
<p> This example uses the StructNew function to create a structure called
"employee" that supplies employee info. Its fields are filled by
the form. After you enter employee information in structure, the
example uses StructKeyArray function to copy all of the keys from
the structure into an array. </p>
<hr size = "2" color = "#0000A0">
<form action = "structkeyarray.cfm">
<table cellspacing = "2" cellpadding = "2" border = "0">
   <tr>
   <td>First Name:</td>
   <td><input name = "firstname" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>Last Name:</td>
   <td><input name = "lastname" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>EMail</td>
   <td><input name = "email" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>Phone:</td>
   <td><input name = "phone" type = "text"
      value = "" hspace = "20" maxlength = "20"></td>
   </tr>
   <tr>
   <td>Company:</td>
   <td><input name = "company" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td><input type = "submit" name = "submit"
      value = "OK"></td>
   <td><b>After you submit the FORM, scroll down to see the array.</b>
   </td>
   </tr>
</table>
</form>
<cfif NOT StructISEmpty(employee)>
   <hr size = "2" color = "#0000A0">
   <cfset keysToStruct = StructKeyArray(employee)>
   <cfloop index = "i" from = "1" to = "#ArrayLen(keysToStruct)#">
      <p><cfoutput>Key#i# is #keysToStruct[i]#</cfoutput></p>
      <p><cfoutput>Value#i# is #employee[keysToStruct[i]]#</cfoutput>
      </p>
   </cfloop>
</cfif>


StructKeyExists

Description

Determines whether a specific key is present in a structure.

Return value

True, if key is in structure; if structure does not exist, ColdFusion throws an exception.

Category

Decision functions, Structure functions

Syntax

StructKeyExists(structure, "key")

See also

Structure functions

Parameters

Parameter | Description
structure | Name of structure to test
key | Key to test

Usage

This function can sometimes be used in place of the IsDefined function, when working with the URL and Form scopes, which are structures. The following pieces of code are equivalent:

cfif IsDefined("Form.JediMaster")>
<cfif StructKeyExists(Form,"JediMaster")>

A structure’s keys are unordered.

Example

<!--- This example shows the use of StructKeyExists. --->
<p>This file is similar to addemployee.cfm, which is called by StructNew,
StructClear, and StructDelete. To test, copy the &LT;CFELSEif&GT;
statement to the appropriate place in addemployee.cfm. It is a custom tag
to add employees. Employee information is passed through the employee
structure (the EMPINFO attribute). In UNIX, you must also add the Emp_ID.

<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif StructIsEmpty(attributes.EMPINFO)>
    <cfoutput>Error. No employee data was passed.</cfoutput>
     <cfexit method = "ExitTag">
   <cfelseIf NOT StructKeyExists(attributes.EMPINFO, "department")>
    <cfscript>StructUpdate(attributes.EMPINFO, "department",
      "Unassigned");
      </cfscript>
    <cfexit method = "ExitTag">
         <cfelse>


StructKeyList

Description

Extracts keys from a ColdFusion structure.

Return value

A list of keys; if structure does not exist, ColdFusion throws an exception.

Category

Structure functions

Syntax

StructKeyList(structure [, delimiter])

See also

Structure functions

Parameters

Parameter | Description
structure | Structure from which to extract a list of keys.
delimiter | Optional. Character that separates keys in list. Default: comma.

Usage

A structure’s keys are unordered.

Example

<!--- This example shows how to use StructKeyList to list the keys
in a structure. It uses StructNew function to create structure
and fills it with information user enters in form fields. --->
<!--- This section creates structure and checks whether Submit has been pressed.
If so, code defines fields in the employee structure with what the
user entered in the form. --->
<cfset employee = StructNew()>
<cfif Isdefined("Form.Submit")>
   <cfif Form.Submit is "OK">
      <cfset employee.firstname = FORM.firstname>
      <cfset employee.lastname = FORM.lastname>
      <cfset employee.email = FORM.email>
      <cfset employee.phone = FORM.phone>
      <cfset employee.company = FORM.company>
   <cfelseIf Form.Submit is "Clear">
      <cfset rc = StructClear(employee)>
   </cfif>
</cfif>
<html>
<head>
   <title>StructKeyList Function</title>
</head>
<body>
<h3>StructKeyList Function</h3>
<h3>Listing the Keys in the Employees Structure</h3>
<p>This example uses StructNew function to create structure "employee" that
supplies employee information. The fields are filled with the
contents of the following form.</p>
<p>After you enter employee information into structure, example uses
<b>StructKeyList</b> function to list keys in structure.</p>
<p>This code does not show how to insert information into a database.
See cfquery for more information about database insertion.
<hr size = "2" color = "#0000A0">
<form action = "structkeylist.cfm">
<table cellspacing = "2" cellpadding = "2" border = "0">
   <tr>
   <td>First Name:</td>
   <td><input name = "firstname" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>Last Name:</td>
   <td><input name = "lastname" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>EMail</td>
   <td><input name = "email" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td>Phone:</td>
   <td><input name = "phone" type = "text"
      value = "" hspace = "20" maxlength = "20"></td>
   </tr>
   <tr>
   <td>Company:</td>
   <td><input name = "company" type = "text"
      value = "" hspace = "30" maxlength = "30"></td>
   </tr>
   <tr>
   <td><input type = "submit" name = "submit"       value = "OK"></td>
   <td><b>After you submit form, scroll down       to see the list.</b></td>
   </tr>
</table>
</form>
<cfif NOT StructISEmpty(employee)>
   <hr size = "2" color = "#0000A0">
   <cfset keysToStruct = StructKeyList(employee,"<li>")>
   <p>Here are the keys to the structure:</p>
   <ul>
   <li>   <cfoutput>#keysToStruct#</cfoutput>
   </ul>
   <p>If fields are correct, we can process new employee information.
If they are not correct, consider rewriting application.</p>
</cfif>


StructNew

Description

Creates a structure.

Return value

A structure.

Category

Structure functions

Syntax

StructNew()

See also

Structure functions

Parameters

None

Example

<!--- Shows StructNew. Calls CF_ADDEMPLOYEE, which uses the |
addemployee.cfm file to add employee record to database. --->
<h1>Add New Employees</h1>
<cfparam name = "FORM.firstname" default = "">
<cfparam name = "FORM.lastname" default = "">
<cfparam name = "FORM.email" default = "">
<cfparam name = "FORM.phone" default = "">
<cfparam name = "FORM.department" default = "">
<cfif FORM.firstname EQ "">
 <p>Please fill out the form.
<cfelse>
   <cfoutput>
  <cfscript>
   employee = StructNew();
   StructInsert(employee, "firstname", FORM.firstname);
   StructInsert(employee, "lastname", FORM.lastname);
   StructInsert(employee, "email", FORM.email);
   StructInsert(employee, "phone", FORM.phone);
   StructInsert(employee, "department", FORM.department);
 </cfscript>
   <p>First name is #StructFind(employee, "firstname")#
   <p>Last name is #StructFind(employee, "lastname")#
   <p>EMail is #StructFind(employee, "email")#
   <p>Phone is #StructFind(employee, "phone")#
   <p>Department is #StructFind(employee, "department")#
   </cfoutput>
<!--- Call the custom tag that adds employees --->
 <CF_ADDEMPLOYEE EMPINFO = "#employee#">
</cfif>


StructSort

Description

Finds and sorts structures that contain top-level key names (strings).

Return value

An array of structures of top-level key names (strings), sorted by the value of the specified subelement. The key values may be simple values or complex elements.

Category

Structure functions

Syntax

StructSort(base, sortType, sortOrder, pathToSubElement)

See also

Structure functions

Parameters

Parameter
Description
base
A ColdFusion struct with one field (an associative array).
sorttype
  • numeric
  • text: case sensitive (all lower-case letters precede the first upper-case letter). Default.
  • textnocase
sortorder
  • asc: ascending (a to z) sort order. Default.
  • desc: descending (z to a) sort order
pathToSubelement
String or a variable that contains one.
Path to apply to each top-level key, to reach element value by which to sort. Default: nothing (top-level entries sorted by their own values).

Usage

The pathToSubElement string does not support array notation; only substructures of structures are supported.

Example

<cfscript>
   salaries = StructNew() ;
   employees = StructNew() ;
   departments = StructNew() ;
   for ( i=1; i lt 6; i=i+1 )
   {
      salary = 120000 - i*10000 ;
      salaries["employee#i#"] = salary ;

      employee = StructNew() ;
      employee["salary"] = salary ;
      // employee.salary = salary ;
      employees["employee#i#"] = employee ;

      departments["department#i#"] = StructNew() ;
      departments["department#i#"].boss = employee ;
   }
</cfscript>

<cfoutput>
<p>list of employees based on the salary (text search): <br>
1) #ArrayToList( StructSort( salaries ) )#<br>
2) #ArrayToList( StructSort( salaries, "text", "ASC" ) )#<br>
3) #ArrayToList( StructSort( salaries, "textnocase", "ASC" ) )#<br>
4) #ArrayToList( StructSort( salaries, "text", "DESC" ) )#<br>
<p>list of employees based on the salary (numeric search): <br>
5) #ArrayToList( StructSort( salaries, "numeric", "ASC" ) )#<br>
6) #ArrayToList( StructSort( salaries, "numeric", "DESC" ) )#<br>
<p>list of employees based on the salary (subfield search): <br>
7) #ArrayToList( StructSort( employees, "numeric", "DESC", "salary" ) )#<br>
8) #ArrayToList( StructSort( employees, "text", "ASC",  "salary" ) )#<br>
<p>list of departments based on the salary (sub-sub-field search): <br>
9) #ArrayToList( StructSort( departments, "text", "ASC", "boss.salary" ) )#<br>
</cfoutput>

<!--- add an invalid element and test that it throws an error --->
<p><p>
<cfset employees[ "employee4" ] = StructNew()>
<cftry>
   <cfset temp = StructSort( employees, "text", "ASC", "salary" )>
   <cfoutput>We have a problem - this was supposed to throw an exception!<br>
</cfoutput>
<cfcatch type="any">
   <cfoutput>
      ERROR: <b>This error was expected!</b><br>
      #cfcatch.message# - #cfcatch.detail#<br>
   </cfoutput>
</cfcatch>
</cftry>


StructUpdate

Description

Updates a key with a value.

Return value

True, on successful execution; if the structure does not exist, ColdFusion throws an error.

Category

Structure functions

Syntax

StructUpdate(structure, key, value)

See also

Structure functions

History

New in ColdFusion MX: this function can be used on XML objects.

Parameters

Parameter | Description
structure | Structure to update
key | Key, the value of which to update
value | New value

Example

<!--- This example shows the use of StructUpdate. --->
<p>This file is similar to addemployee.cfm, which is called by StructNew,
StructClear, and StructDelete. To test this file, copy the
&LT;CFELSEIF&GT; statement to the appropriate place in
addemployee.cfm. It is an example of a custom tag used to add
employees. Employee information is passed through the employee
structure (the EMPINFO attribute). In UNIX, you must also add the Emp_ID.

<cfswitch expression = "#ThisTag.ExecutionMode#">
  <cfcase value = "start">
   <cfif StructIsEmpty(attributes.EMPINFO)>
    <cfoutput>Error. No employee data was passed.</cfoutput>
      <cfexit method = "ExitTag">
   <cfelseIf StructFind(attributes.EMPINFO, "department") EQ "">
    <cfscript>
     StructUpdate(attributes.EMPINFO, "department", "Unassigned");
    </cfscript>
    <cfexit method = "ExitTag">
         <cfelse>


Tan

Description

Calculates the tangent of an angle.

Return value

A number; the tangent of an angle.

Category

Mathematical functions

Syntax

Tan(number)

See also

Atn , ASin , Cos , Sin , Pi

Parameters

Parameter | Description
number | Angle, in radians. To convert an angle from degrees to radians, use the PI function, and multiply the degrees by PI/180.

Example

<h3>Tan Example</h3>
<p>Returns the tangent of an angle.
<p>Tan(1): <cfoutput>#Tan(1)#</cfoutput>
<p>Tan(Pi()/4): <cfoutput>#Tan(Pi()/4)#</cfoutput>


TimeFormat

Description

Formats a time value.

Return value

A custom-formatted time value. If no mask is specified, returns a time value using the hh:mm tt format. For international time formatting, see LSTimeFormat.

Category

Date and time functions, Display and formatting functions

Syntax

TimeFormat(time [, mask ])

See also

CreateTime , Now , ParseDateTime

History

New in ColdFusion MX: This function processes extra characters within the mask value differently than in earlier releases, as follows:

  • ColdFusion 5 and earlier: the function returns the time format and an apostrophe-delimited list of the extra characters. For example, TimeFormat(now(), "hh:mm:ss dog") returns 8:17:23 d'o'g.
  • ColdFusion MX: the function returns the time format and the extra characters. For example, for the call above, it returns 8:17:23 dog.

If the extra characters are single-quoted (for example, hh:mm:ss 'dog'), ColdFusion 5 and ColdFusion MX return the time format and the extra characters: 8:17:23 dog.

New in ColdFusion MX: This function supports the short, medium, long, and full mask attribute options.

Parameters

Parameter
Description
time
A date/time value or string to convert
mask
Masking characters that determine the format:
  • h: Hours; no leading zero for single-digit hours (12-hour clock)
  • hh: Hours; leading zero for single-digit hours (12-hour clock)
  • H: Hours; no leading zero for single-digit hours (24-hour clock)
  • HH: Hours; leading zero for single-digit hours (24-hour clock)
  • m: Minutes; no leading zero for single-digit minutes
  • mm: Minutes; a leading zero for single-digit minutes
  • s: Seconds; no leading zero for single-digit seconds
  • ss: Seconds; leading zero for single-digit seconds
  • t: One-character time marker string, such as A or P
  • tt: Multiple-character time marker string, such as AM or PM
  • short
  • medium
  • long
  • full

Usage

When passing a date/time value as a string, you must enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date/time object.

Database query results for date and time values can vary in sequence and formatting unless you use functions to format the results. To ensure that dates and times display with appropriate formatting, and that users of your ColdFusion application are not confused by dates and times displayed, Macromedia recommends that you use the DateFormat and TimeFormat functions to format date and time values from queries. For more information and examples, see TechNote 22183, "ColdFusion Server (5 and 4.5.x) with Oracle: Formatting Date and Time Query Results," at .

Example

<cfset todayDate = #Now()#>
<body>
<h3>TimeFormat Example</h3>
<p>Today’s date is <cfoutput>#todayDate#</cfoutput>.
<p>Using Timeformat, we can display the value in different ways:
<cfoutput>
<ul>
   <li>#TimeFormat(todayDate)#
   <li>#TimeFormat(todayDate, "hh:mm:ss")#
   <li>#TimeFormat(todayDate, "hh:mm:sst")#
   <li>#TimeFormat(todayDate, "hh:mm:sstt")#
   <li>#TimeFormat(todayDate, "HH:mm:ss")#
</ul>
</cfoutput>
</body>


ToBase64

Description

Calculates the Base64 representation of a string or binary object. The Base64 format uses printable characters, allowing binary data to be sent in forms and e-mail, and stored in a database or file.

Return value

The Base64 representation of a string or binary object.

Category

Conversion functions, Other functions, String functions

Syntax

ToBase64(string or binary_object[, encoding])

See also

  • cffile for information about loading and reading binary data
  • cfwddx for information about serializing and deserializing binary data
  • IsBinary and ToBinary for checking for binary data and converting a Base64 object to binary format

History

New in ColdFusion MX: the encoding attribute is new.

Parameters

Parameter
Description
string or binary_object
A string, the name of a string, or a binary object.
encoding
For a string, defines how characters are represented in a byte array:
  • US-ASCII
  • ISO-8859-1
  • UTF-8
  • UTF-16
Default: the encoding option of the page on which the function is called. See cfcontent.
The Java platform determines the available options.
For a binary object, this parameter is ignored.

Usage

Base64 provides -bit encoding of 8-bit ASCII characters. High ASCII values and binary objects are not safe for transport over internet protocols such as HTTP and SMTP; using Base64 safely sends ASCII and binary data over these protocols.

Base64 lets you store binary objects in a database.

Note: To reverse Base64 encoding of a string, you can convert it to a binary object, then convert the binary object to a string, using the toString function.

Example

<h3>ToBase64 Example</h3>
<!--- Initialize data. ---->
<cfset charData = "">
<!--- Create string of ASCII characters (32-255); concatenate them --->
<cfloop index = "data" from = "32" to = "255">
   <cfset ch = chr(data)>
   <cfset charData = charData & ch>
</cfloop>
<p>
The following string is the concatenation of all characters (32 to 255)
from the ASCII table.<br>
<cfoutput>#charData#</cfoutput>
</p>
<!--- Create a Base64 representation of this string. ---->
<cfset data64 = toBase64(charData)>

<!----- Convert string to binary. ------->
<cfset binaryData = toBinary(data64)>
<!--- Convert binary back to Base64. ---->
<cfset another64 = toBase64(binaryData)>
<!---- Compare another64 with data64 to ensure that they are equal. ---->
<cfif another64 eq data64>
   <h3>Base64 representations are identical.</h3>
<cfelse>
   <h3>Conversion error.</h3>
</cfif>


ToBinary

Description

Calculates the binary representation of Base64-encoded data.

Return value

The binary representation of Base64-encoded data.

Category

Conversion functions, Other functions, String functions

Syntax

ToBinary(string_in_Base64 or binary_value)

See also

  • cffile for information about loading and reading binary data
  • cfwddx for information about serializing and deserializing binary data
  • IsBinary and ToBase64 for checking format and converting to Base64
  • Len for determining the length of a binary object

Parameters

Parameter
Description
string_in_Base64 or binary_value
A string or a variable that contains one:
  • In Base64 format to convert to binary
  • In binary format to test whether it is valid

Usage

Base64 provides 6-bit encoding of 8-bit ASCII characters. From Base64 data, you can recreate the binary object that it represents, such as a GIF, JPG, or executable file.

Example

<h3>ToBinary Example</h3>
<!---- Initialize data. ---->
<cfset charData = "">
<!---- Create a string of ASCII characters (32-255); concatenate them. ---->
<cfloop index = "data" from = "32" to = "255">
   <cfset ch = chr(data)>
   <cfset charData = charData & ch>
</cfloop>
<p>The following string is the concatenation of all characters (32 to 255)
from the ASCII table.<br>
<cfoutput>#charData#</cfoutput></p>
<!----- Create a Base64 representation of this string. ----->
<cfset data64 = toBase64(charData)>

<!--- Convert string to binary. ---->
<cfset binaryData = toBinary(data64)>
<!--- Convert binary back to Base64. --->
<cfset another64 = toBase64(binaryData)>
<!---- Compare another64 with data64 to ensure that they are equal. ---->
<cfif another64 eq data64>
   <h3>Base64 representation of binary data is identical to the Base64
representation of string data.</h3>
<cfelse>
   <h3>Conversion error.</h3>
</cfif>


ToString

Description

Converts a value to a string.

Return value

A string.

Category

Conversion functions, Other functions, String functions

Syntax

ToString(any_value[, encoding])

See also

  • ToBase64 ToBinary

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode character values 0–65535. (ColdFusion 5 and earlier releases supported ASCII values 1–255.)

New in ColdFusion MX: the encoding attribute is new.

Parameters

Parameter
Description
any_value
Value to convert to a string
encoding
Defines how characters are represented in a string:
  • US-ASCII
  • ISO-8859-1
  • UTF-8
  • UTF-16
Default: the encoding option of the page on which the function is called. See cfcontent.
The Java platform determines the available options.

Usage

This function can convert simple values and binary values that do not contain Byte zero. If this function cannot convert a value, it throws an exception. This function can convert an XML document object to a string representation.

Note: You can use this function to reverse Base64 encoding of a string. Convert the Base64 encoded object to a binary object, then use this function to convert the binary object to a string.

Example

<h3>ToString Example</h3>
<!---- Initialize data. ------>
<cfset charData = "">
<!----- Create string of ASCII characters (32-255) and concatenate them. ---->
<cfloop index = "data" from = "32" to = "255">
   <cfset ch = chr(data)>
   <cfset charData = charData & ch>
</cfloop>
<p>The following string is the concatenation of characters (32 to 255)
from the ASCII table.<br>
<cfoutput>#charData#</cfoutput></p>

<!------ Create a Base64 representation of this string. ---->
<cfset data64 = toBase64(#charData#)>
<p>
The following string is the Base64 representation of the string.<br>
<cfoutput>#data64#</cfoutput></p>
<!---- Create a binary representation of Base64 data. --->
<cfset dataBinary = toBinary(data64)>

<!---- Create the string repesentation of the binary data. ----->
<cfset dataString = toString(dataBinary)>
<p>The following is the string representation of the binary data.<br>
<cfoutput>#dataString#</cfoutput></p>


Trim

Description

Removes leading and trailing spaces from a string.

Return value

A copy of string, after removing leading and trailing spaces.

Category

String functions

Syntax

Trim(string)

See also

LTrim, RTrim

Parameters

Parameter | Description
string | A string or a variable that contains one

Example

<h3>Trim Example</h3>
<cfif IsDefined("FORM.myText")>
   <cfoutput>
      <pre>
         Your string:   "#FORM.myText#"
         Your string:   "#trim(FORM.myText)#"
         (trimmed on both sides)
      </pre>
   </cfoutput>
</cfif>
<form action = "trim.cfm">
<p>Type in some text, and it will be modified by trim to remove leading
spaces from the left and right
<p><input type = "Text" name = "myText" value = "   TEST   ">
<p><input type = "Submit" name = "">
</form>


UCase

Description

Converts the alphabetic characters in a string to uppercase.

Return value

A copy of a string, converted to uppercase.

Category

String functions

Syntax

UCase(string)

See also

LCase

Parameters

Parameter | Description
string | A string or a variable that contains one

Example

<h3>UCase Example</h3>

<cfif IsDefined("FORM.sampleText")>
   <cfif FORM.sampleText is not "">
      <p>Your text, <cfoutput>#FORM.sampleText#</cfoutput>,
returned in uppercase is <cfoutput>#UCase(FORM.sampleText)#</
cfoutput>.
   <cfelse>
      <p>Please enter some text.
   </cfif>
</cfif>

<form action = "ucase.cfm">
<p>Enter your sample text, and press "submit" to see the text returned in
uppercase:
<p><input type = "Text" name = "SampleText" value = "sample">

<input type = "Submit" name = "" value = "submit">
</form>


URLDecode

Description

Decodes a URL-encoded string.

Return value

A copy of a string, decoded.

Category

Conversion functions, Other functions, String functions

Syntax

URLDecode(urlEncodedString[, charset])

See also

URLEncodedFormat

History

New in ColdFusion MX: ColdFusion supports the Java UCS-2 representation of Unicode character values 0–65535. (Earlier releases supported ASCII values.)

New in ColdFusion MX: the charset parameter is new.

Parameters

Parameter
Description
urlEncodedString
URL-encoded string or a variable that contains one.
charset
A Java character set name. Optional.
The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Usage

URL encoding formats some characters with a percent sign and the two-character hexadecimal representation of the character. For example, a character whose code is 129 is encoded as %81. A space is encoded with a plus sign.

Query strings in HTTP are always URL-encoded.

Example

This example creates, encodes, and decodes a string that contains ASCII character codes.

<cfscript>
   // Build string
   s = "";
   for (c = 1; c lte 256; c = c + 1)
   {
      s = s & chr(c);
   }
   // Encode string and display result
   enc = URLEncodedFormat(s);
   writeOutput("Encoded string is: '#enc#'.<br>");
   // Decode and compare result with original
   dec = URLDecode(enc);
   if (dec neq s)
   {
      writeOutput("Decoded is not the same as encoded.");
   }
   else
   {
      writeOutput("All's quiet on the Western front.");
   }
</cfscript>


URLEncodedFormat

Description

Generates a URL-encoded string. For example, it replaces spaces with %20, and non-alphanumeric characters with equivalent hexadecimal escape sequences. Passes arbitrary strings within a URL (ColdFusion automatically decodes URL parameters that are passed to a page).

Return value

A copy of a string, URL-encoded.

Category

Conversion functions, Other functions, String functions

Syntax

URLEncodedFormat(string [, charset ])

See also

URLDecode

History

New in ColdFusion MX: the charset parameter is new.

Parameters

Parameter
Description
string
A string or a variable that contains one
charset
A Java character set name. Optional.
The following values are typically used:
  • UTF-8
  • ISO-8859-1
  • UTF-16
  • US-ASCII
  • UTF-16BE
  • UTF-16LE
For a list of character sets, see:
http://www.w3.org/International/O-charset-lang.html

Usage

URL encoding formats some characters with a percent sign and the two-character hexadecimal representation of the character. For example, a character whose code is 129 is encoded as %81. A space is encoded with a plus sign.

Query strings in HTTP are always URL-encoded.

Example

<h3>URLEncodedFormat Example</h3>
<cfif IsDefined("url.myExample")>
   <p>The url variable url.myExample was passed from the previous link ...
   its value is:
   <br><b>"<cfoutput>#url.myExample#</cfoutput>"</b>
</cfif>
<p>This function returns a URL encoded string.
<cfset s = "My url-encoded string has special characters & other stuff">
<p> <A HREF = "urlencodedformat.cfm?myExample=<cfoutput>#URLEncodedFormat(s)#
</cfoutput>">Click me</A>


URLSessionFormat

Description

Depending on whether a client computer accepts cookies, this function does the following:

  • If the client does not accept cookies: automatically appends all required client identification information to a URL
  • If the client accepts cookies: does not append information

This function automatically determines which identifiers are required, and sends only the required information. It provides a more secure and robust method for supporting client identification than manually encoding the information in each URL, because it sends only required information, when it is required, and it is easier to code.

Return value

A URL; if cookies are disabled for the browser, client and session data are appended.

Category

Other functions

Syntax

URLSessionFormat(request_URL)

Parameters

Parameter | Description
request_URL | URL of a ColdFusion page

Usage

In the following example, the cfform tag posts a request to another page and sends the client identification, if required. If cookie support is detected, the function returns the following:

myactionpage.cfm

If the detected cookie is not turned on, or cookie support cannot be reliably detected, the function return value is as follows:

myactionpage.cfm?jsessionid=xxxx;cfid=xxxx&cftoken=xxxxxxxx

Example

<cfform
method="Post"
action="#URLSessionFormat("MyActionPage.cfm")#>


Val

Description

Converts numeric characters that occur at the beginning of a string to a number.

Return value

A number. If conversion fails, returns zero.

Category

Conversion functions, String functions

Syntax

Val(string)

See also

IsNumeric

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

This function works as follows:

  • If TestValue = "234A56?7'", Val(TestValue) returns 234
  • If TestValue = "234'5678'9?'", Val(TestValue) returns 234
  • If TestValue = "BG234", Val(TestValue) returns the value 0, (not an error)
  • If TestValue = "0", Val(TestValue) returns the value 0, (not an error)

Example

<h3>Val Example</h3>
<cfif IsDefined("FORM.theTestValue")>
   <cfif Val(FORM.theTestValue) is not 0>
      <h3>The string <cfoutput>#DE(FORM.theTestValue)#</cfoutput>
can be converted to a number:
      <cfoutput>#Val(FORM.theTestValue)#</cfoutput></h3>
   <cfelse>
      <h3>The beginning of the string <cfoutput>#DE(FORM.theTestValue)#
       </cfoutput> cannot be converted to a number</h3>
   </cfif>
</cfif>
<form action = "val.cfm">
<p>Enter a string, and determine whether its beginning can be evaluated
to a numeric value.
<p>
<input type = "Text"
   name = "TheTestValue"
   value = "123Boy">
<input type = "Submit"
   value = "Is the beginning numeric?"
   name = "">
</form>


ValueList

Description

Inserts a delimiter between each value in an executed query. ColdFusion does not evaluate the arguments.

Return value

A delimited list of the values of each record returned from an executed query.

Category

Other functions, Query functions

Syntax

ValueList(query.column [, delimiter ])

See also

QuotedValueList

Parameters

Parameter | Description
query.column | Name of an executed query and column. Separate query name and column name with a period.
delimiter | A delimiter character to separate column data items.

Example

<h3>ValueList Example</h3>

<!--- use the contents of a query to create another dynamically --->
<cfquery name = "GetDepartments" datasource = "cfsnippets">
   SELECT Dept_ID FROM Departments
   WHERE Dept_ID IN (‘BIOL’)
</cfquery>

<cfquery name = "GetCourseList" datasource = "cfsnippets">
SELECT *
   FROM CourseList
   WHERE Dept_ID IN (‘#ValueList(GetDepartments.Dept_ID)#’)
</cfquery>

<cfoutput QUERY = "GetCourseList" >
<pre>#Course_ID#   #Dept_ID#   #CorNumber#   #CorName#</pre>
</cfoutput>


Week

Description

From a date/time object, determines the week number within the year.

Return value

An integer in the range 1–53; the ordinal of the week, within the year.

Category

Date and time functions

Syntax

Week(date)

See also

DatePart

Parameters

Parameter | Description
date | A date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing date as a string, enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date.

Example

<h3>Week Example</h3>
<cfif IsDefined("FORM.year")>
More information about your date:
<cfset yourDate = CreateDate(FORM.year, FORM.month, FORM.day)>
<cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#, day
       #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(YourDate)# in the month of
       #MonthAsString(Month(yourDate))#, which has #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(yourDate)# (day
       #DayofYear(yourDate)# of #DaysinYear(yourDate)#). <br>
   <cfif IsLeapYear(Year(yourDate))>This is a leap year
      <cfelse>This is not a leap year
   </cfif>
</cfoutput>
</cfif>


WriteOutput

Description

Appends text to the page-output stream.

This function writes to the page-output stream regardless of conditions established by the cfsetting tag.

Category

Other functions

Syntax

WriteOutput(string)

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

Within the cfquery and cfmail tags, this function does not output to the current page; it writes to the current SQL statement or mail text. Do not use WriteOutput within cfquery and cfmail.

Although you can call this function anywhere within a page, it is most useful inside a cfscript block.

Example

...
<cfscript>
  employee = StructNew();
  StructInsert(employee, "firstname", FORM.firstname);
  StructInsert(employee, "lastname", FORM.lastname);
  StructInsert(employee, "email", FORM.email);
  StructInsert(employee, "phone", FORM.phone);
  StructInsert(employee, "department", FORM.department);
  WriteOutput("About to add " & FORM.firstname & " " & FORM.lastname);
</cfscript>


XmlChildPos

Description

Gets the position of a child element within an XML document object.

Return value

The position, in an XmlChildren array, of the Nth child that has the specified name.

Category

Extensibility functions , XML functions

Syntax

XmlChildPos(elem, childName, N)

See also

cfxml , IsXmlDoc , XmlChildPos , XmlFormat , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
elem | XML element within which to search
childName | XML child element for which to search
N | Index of XMLchild element for which to search

Usage

The returned index can be used in the ArrayInsertAt and ArrayDeleteAt functions.

Example

This example searches the XML document object mydoc.employee.XmlChildren for the mydoc.employee.name[2] element:

XmlChildPos(mydoc.employee, "name", 2)


XmlElemNew

Description

Creates an XML document object element.

Return value

An XML document object element.

Category

Extensibility functions , XML functions

Syntax

XmlElemNew(xmlObj, childName)

See also

cfxml , IsXmlDoc , XmlChildPos , XmlFormat , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
xmlObj | The name of an XML object. An XML document or an element.
childName | The name of the element to create. This element becomes a child element of xmlObj in the tree.

Example

The following example creates and displays a ColdFusion document object. For more information on this example, see Developing ColdFusion MX Applications with CFML.

Example

<cfset testVar = True>
<cfscript>
   MyDoc = XmlNew();
   MyDoc.xmlRoot = XmlElemNew(MyDoc,"MyRoot");
   if (testVar IS TRUE)
      MyDoc.MyRoot.XmlText = "The value of testVar is True.";
   else
      MyDoc.MyRoot.XmlText = "The value of testVar is False.";
   for (i = 1; i LTE 4; i = i + 1)
      {
      MyDoc.MyRoot.XmlChildren[i] = XmlElemNew(MyDoc,"childNode");
      MyDoc.MyRoot.XmlChildren[i].XmlText = "This is Child node " & i &".";
      }
</cfscript>
<cfdump var=#MyDoc#>


XmlFormat

Description

Escapes special XML characters in a string, so that the string is safe to use with XML.

Return value

A copy of string that is safe to use with XML.

Category

Extensibility functions , String functions, XML functions

Syntax

XmlFormat(string)

See also

cfxml , IsXmlDoc , XmlChildPos , XmlChildPos , XmlNew , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
string | A string or a variable that contains one

Usage

The characters that this function escapes include the following:

  • Greater than symbol (>)
  • Less than symbol (<)
  • Single quotation mark (')
  • Double quotation mark (")
  • Ampersand symbol (&)

Example

<h3>XMLFormat</h3>
<p>This example shows how XMLFormat is used to escape special
XML characters and make the use of XML with ColdFusion easy.</p>
<XMP>
<?xml version = "1.0"?>
<cfoutput>
<someXML>
   <someElement someAttribute = "#XMLFormat("'a quoted value'")#>
      #XMLFormat(   "Body of element to be passed here.")#
   </someElement>
</someXML>
</cfoutput>
</XMP>


XmlNew

Description

Creates an XML document object.

Return value

An empty XML document object.

Category

Extensibility functions , XML functions

Syntax

XmlNew([caseSensitive])

See also

cfxml , IsXmlDoc , XmlChildPos , XmlChildPos , XmlFormat , XmlParse , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter
Description
caseSensitive
Determines how ColdFusion processes the case of XML document object component identifiers
  • yes: maintains case
  • no. ColdFusion ignores case. Default.

Usage

An XML document object is represented in ColdFusion as a structure.

The caseSensitive attribute value determines whether identifiers whose characters are of varying case, but are otherwise the same, refer to different components. For example:

  • If caseSensitive = "no", the names mydoc.employee.name[1] and mydoc.employee.NAME[1] refer to the same element
  • If caseSensitive = "yes", these names refer to two distinct elements

The following example creates and displays a ColdFusion document object. For more information on this example, see Developing ColdFusion MX Applications with CFML.

Example

<cfset testVar = True>
<cfscript>
   MyDoc = XmlNew();
   MyDoc.xmlRoot = XmlElemNew(MyDoc,"MyRoot");
   if (testVar IS TRUE)
      MyDoc.MyRoot.XmlText = "The value of testVar is True.";
   else
      MyDoc.MyRoot.XmlText = "The value of testVar is False.";
   for (i = 1; i LTE 4; i = i + 1)
      {
      MyDoc.MyRoot.XmlChildren[i] = XmlElemNew(MyDoc,"childNode");
      MyDoc.MyRoot.XmlChildren[i].XmlText = "This is Child node " & i &".";
      }
</cfscript>
<cfdump var=#MyDoc#>


XmlParse

Description

Converts an XML document that is represented as a string variable into an XML document object.

Return value

An XML document object.

Category

Conversion functions , Extensibility functions , XML functions

Syntax

XmlParse(xmlString [, caseSensitive ] )

See also

cfxml , IsXmlDoc , XmlChildPos , XmlChildPos , XmlFormat , XmlNew , XmlSearch , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter
Description
xmlString
An XML document object string
caseSensitive
  • yes: maintains the case of document elements and attributes
  • no. Default.

Usage

The caseSensitive attribute value determines whether identifiers whose characters are of varying case, but are otherwise the same, refer to different components. For example:

  • If caseSensitive = "no", the names mydoc.employee.name[1] and mydoc.employee.NAME[1] refer to the same element
  • If caseSensitive = "yes", these names refer to two distinct elements

If the XML document is represented by a string variable, use the XmlParse tag directly on the variable. For example, if your application uses cfhttp action="get" to get the XML document, use the following code to create the XML document object:

<cfset myXMLDocument = XmlParse(cfhttp.fileContent)>

If the XML document is in a file, use the cffile tag to convert the file to a CFML variable, then use the XmlParse tag on the resulting variable. For example, if the XML document is in the file C:\temp\myxmldoc.xml, use the following code to convert the file to an XML document object:

<cffile action="read" file="C:\temp\myxmldoc.xml" variable="XMLFileText">
<cfset myXMLDocument=XmlParse(XMLFileText)>

Note: If the file is not encoded with the ASCII or Latin-1 character set, use the cffile tag charset attribute to specify the file’s character set. For example, if the file is encoded in UTF, specify charset="UTF-8".


XmlSearch

Description

Uses an XPath language expression to search an XML document that is represented as a string variable.

Return value

An array of XML object nodes that match the search criteria.

Category

Extensibility functions , XML functions

Syntax

XmlSearch(xmlDoc, xPathString)

See also

cfxml , IsXmlDoc , XmlChildPos , XmlChildPos , XmlFormat , XmlNew , XmlParse , XmlTransform

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
xmlDoc | XML document object
xPathString | XPath expression

Usage

XPath is specified by the World-Wide Web Consortium. For detailed information on XPath, see the W3C website at http://www.w3.org/TR/xpath.

Example

The following example extracts the elements named last, which contain employee last names, from the employeesimple.xml file, and displays the names.

<cffile action="read"
   file="C:\inetpub\wwwroot\examples\employeesimple.xml"
   variable="myxml">
<cfscript>
   myxmldoc = XmlParse(myxml);
   selectedElements = XmlSearch(myxmldoc, "/employee/name/last");
   for (i = 1; i LTE ArrayLen(selectedElements); i = i + 1)
      writeoutput(selectedElements[i].XmlText & "<br>");
</cfscript>


XmlTransform

Description

Applies an Extensible Stylesheet Language Transformation (XSLT)) to an XML document object that is represented as a string variable. An XSLT converts an XML document to another format or representation by applying an Extensible Stylesheet Language (XSL) stylesheet to it. For more information, see Developing ColdFusion MX Applications with CFML.

Return value

A string; an XML document after the XSLT is applied

Category

Conversion functions , Extensibility functions , XML functions

Syntax

XmlTransform(xmlString | xmlObj, xslString)

See also

cfxml , IsXmlDoc , XmlChildPos , XmlChildPos , XmlFormat , XmlNew , XmlParse , XmlSearch

History

New in ColdFusion MX: this function is new.

Parameters

Parameter | Description
xmlString | xmlObj | A string that represents the XML document, or a parsed object representation of it.
xslString | XSLT transformation to apply.


Year

Description

From a date/time object, gets the year value.

Return value

The year value of date.

Category

Date and time functions

Syntax

Year(date)

See also

DatePart, IsLeapYear

Parameters

Parameter | Description
date | A date/time object in the range 100 AD–9999 AD. See How ColdFusion processes two-digit year values.

Usage

When passing a date as a string, enclose it in quotation marks. Otherwise, it is interpreted as a number representation of a date.

Example

<h3>Year Example</h3>
<cfif IsDefined("FORM.year")>
   More information about your date:
   <cfset yourDate = CreateDate(FORM.year,FORM.month,FORM.day)>
   <cfoutput>
   <p>Your date, #DateFormat(yourDate)#.
   <br>It is #DayofWeekAsString(DayOfWeek(yourDate))#,
day #DayOfWeek(yourDate)# in the week.
   <br>This is day #Day(yourDate)#
in the month of #MonthAsString(Month(yourDate))#,
which has #DaysInMonth(yourDate)# days.
   <br>We are in week #Week(yourDate)# of #Year(YourDate)#
(day #DayofYear(yourDate)# of #DaysinYear(yourDate)#). <br>
   <cfif IsLeapYear(Year(yourDate))>
      This is a leap year
      <cfelse>This is not a leap year
   </cfif>
   </cfoutput>
</cfif>


YesNoFormat

Description

Evaluates a number or Boolean value.

Return value

Yes, for a non-zero value; No, otherwise.

Category

Decision functions, Display and formatting functions

Syntax

YesNoFormat(value)

See also

IsBinary, IsNumeric

Parameters

Parameter | Description
value | A number or Boolean value

Example

<h3>YesNoFormat Example</h3>
<p>The YesNoFormat function returns non-zero values as "Yes"; zero values as "No".

<cfoutput>
<ul>
   <li>YesNoFormat(1):   #YesNoFormat(1)#
   <li>YesNoFormat(0):   #YesNoFormat(0)#
   <li>YesNoFormat("1123"):   #YesNoFormat("1123")#
   <li>YesNoFormat("No"):   #YesNoFormat("No")#
   <li>YesNoFormat(True):   #YesNoFormat(True)#
</ul>
</cfoutput>

Previous


ColdFusion C++ CFX Reference

This chapter describes the CFXAPI classes and members.

Contents
  • C++ class overview
  • Deprecated class members
  • CCFXException class
  • CCFXQuery class
  • CCFXRequest class
  • CCFXStringSet Class
Next


C++ class overview

A list of CFXAPI classes and members follows.

Class
Member
CCFXException class
CCFXException::GetError
CCFXException::GetDiagnostics
CCFXQuery class
CCFXQuery::AddRow
CCFXQuery::GetColumns
CCFXQuery::GetData
CCFXQuery::GetName
CCFXQuery::GetRowCount
CCFXQuery::SetData
CCFXRequest class
CCFXRequest::AddQuery
CCFXRequest::AttributeExists
CCFXRequest::CreateStringSet
CCFXRequest::Debug
CCFXRequest::GetAttribute
CCFXRequest::GetAttributeList
CCFXRequest::GetCustomData
CCFXRequest::GetQuery
CCFXRequest::ReThrowException
CCFXRequest::SetCustomData
CCFXRequest::SetVariable
CCFXRequest::ThrowException
CCFXRequest::Write
CCFXRequest::WriteDebug
CCFXStringSet Class


Deprecated class members

The following CFXAPI classes and members are deprecated. Do not use them in new applications. They do not work, and might cause an error, in later releases.

Class | Deprecated member | Deprecated as of this ColdFusion Server release
CCFXQuery Class | CCFXQuery::SetQueryString CCFXQuery::SetTotalTime | ColdFusion MX ColdFusion MX
CCFXRequest Class | CCFXRequest::GetSetting | ColdFusion MX


CCFXException class

An abstract class that represents an exception thrown during processing of a ColdFusion Extension (CFX) procedure.

Exceptions of this type can be thrown by CCFXRequest class, CCFXQuery class, and CCFXStringSet Class. Your ColdFusion Extension code must be written to handle exceptions of this type. For more information, see CCFXRequest::ThrowException and CCFXRequest::ReThrowException.


Class members

virtual LPCSTR GetError() | The CCFXException::GetError function returns a general error message.
virtual LPCSTR GetDiagnostic() | The CCFXException::GetDiagnostics function returns detailed error information.


CCFXException::GetError

Description

Provides basic user output for exceptions that occur during processing.


CCFXException::GetDiagnostics

Description

Provides detailed user output for exception that occur during processing.

Example

This code block shows how GetError and GetDiagnostics work with ThrowException and ReThrowException.

// Write output back to the user here...
pRequest->Write( "Hello from CFX_FOO2!" ) ;
pRequest->ThrowException("User Error", "You goof'd...");

// Output optional debug info
if ( pRequest->Debug() )
{
               pRequest->WriteDebug( "Debug info..." ) ;
}

// Catch Cold Fusion exceptions & re-raise them
catch( CCFXException* e )
{
               // This is how you would pull the error information
               LPCTSTR strError = e->GetError();
               LPCTSTR strDiagnostic = e->GetDiagnostics();

               pRequest->ReThrowException( e ) ;
}

// Catch ALL other exceptions and throw them as
// Cold Fusion exceptions (DO NOT REMOVE! --
// this prevents the server from crashing in
// case of an unexpected exception)
catch( ... )
{
               pRequest->ThrowException(
               "Error occurred in tag CFX_FOO2",
               "Unexpected error occurred while processing tag." ) ;
}


CCFXQuery class

An abstract class that represents a query used or created by a ColdFusion Extension (CFX). Queries contain one or more columns of data that extend over a varying number of rows.


Class members

virtual int AddRow() | CCFXQuery::AddRow adds a row to a query.
virtual int AddRow() virtual CCFXStringSet* GetColumns | CCFXQuery::GetColumns retrieves a list of a query's column names.
virtual LPCSTR GetData( int iRow, int iColumn ) | CCFXQuery::GetData retrieves a data element from a row and column of a query.
virtual LPCSTR GetName() | CCFXQuery::GetName retrieves the name of a query.
virtual int GetRowCount() | CCFXQuery::GetRowCount retrieves the number of rows in a query.
virtual void SetData( int iRow, int iColumn, LPCSTR lpszData ) | CCFXQuery::SetData sets a data element within a row and column of a query.
virtual void SetQueryString( LPCSTR lpszQuery ) | This function is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.
virtual void SetTotalTime( DWORD dwMilliseconds ) | This function is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.


CCFXQuery::AddRow

Syntax

int CCFXQuery::AddRow(void)

Description

Add a row to the query. Call this function to append a row to a query.

Returns

Returns the index of the row that was appended to a query.

Example

The following example shows the addition of two rows to a three-column ('City', 'State', and 'Zip') query:

// First row
int iRow ;
iRow = pQuery->AddRow() ;
pQuery->SetData( iRow, iCity, "Minneapolis" ) ;
pQuery->SetData( iRow, iState, "MN" ) ;
pQuery->SetData( iRow, iZip, "55345" ) ;

// Second row
iRow = pQuery->AddRow() ;
pQuery->SetData( iRow, iCity, "St. Paul" ) ;
pQuery->SetData( iRow, iState, "MN" ) ;
pQuery->SetData( iRow, iZip, "55105" ) ;


CCFXQuery::GetColumns

Syntax

CCFXStringSet* CCFXQuery::GetColumns(void)

Description

Retrieves a list of the column names contained in a query.

Returns

Returns an object of CCFXStringSet Class that contains a list of the columns in the query. ColdFusion automatically frees the memory that is allocated for the returned string set, after the request is completed.

Example

The following example gets the list of columns, then iterates over the list, writing each column name back to the user:

// Get the list of columns from the query
CCFXStringSet* pColumns = pQuery->GetColumns() ;
int nNumColumns = pColumns->GetCount() ;

// Print the list of columns to the user
pRequest->Write( "Columns in query: " ) ;
for( int i=1; i<=nNumColumns; i++ )
{
   pRequest->Write( pColumns->GetString( i ) ) ;
   pRequest->Write( " " ) ;
}


CCFXQuery::GetData

Syntax

LPCSTR CCFXQuery::GetData(int iRow, int iColumn)

Description

Gets a data element from a row and column of a query. Row and column indexes begin with 1. You can determine the number of rows in a query by calling CCFXQuery::GetRowCount. You can determine the number of columns in a query by retrieving the list of columns using CCFXQuery::GetColumns, and then calling CCFXStringSet::GetCount on the returned string set.

Returns

Returns the value of the requested data element.

Parameters

Parameter | Description
iRow | Row to retrieve data from (1-based)
iColumn | Column to retrieve data from (1-based)

Example

The following example iterates over the elements of a query and writes the data in the query back to the user in a simple, space-delimited format:

int iRow, iCol ;
int nNumCols = pQuery->GetColumns()->GetCount() ;
int nNumRows = pQuery->GetRowCount() ;
for ( iRow=1; iRow<=nNumRows; iRow++ )
{
   for ( iCol=1; iCol<=nNumCols; iCol++ )
   {
   pRequest->Write( pQuery->GetData( iRow, iCol ) ) ;
   pRequest->Write( " " ) ;
   }
   pRequest->Write( "<BR>" ) ;
}


CCFXQuery::GetName

Syntax

LPCSTR CCFXQuery::GetName(void)

Description

Returns the name of a query.

Example

The following example retrieves the name of a query and writes it back to the user:

CCFXQuery* pQuery = pRequest->GetQuery() ;
pRequest->Write( "The query name is: " ) ;
pRequest->Write( pQuery->GetName() ) ;


CCFXQuery::GetRowCount

Syntax

LPCSTR CCFXQuery::GetRowCount(void)

Description

Returns the number of rows contained in a query.

Example

The following example retrieves the number of rows in a query and writes it back to the user:

CCFXQuery* pQuery = pRequest->GetQuery() ;
char buffOutput[256] ;
wsprintf( buffOutput,
   "The number of rows in the query is %ld.",
   pQuery->GetRowCount() ) ;
pRequest->Write( buffOutput ) ;


CCFXQuery::SetData

Syntax

void CCFXQuery::SetData(int iRow, int iColumn, LPCSTR lpszData)

Description

Sets a data element within a row and column of a query. Row and column indexes begin with 1. Before calling SetData for a given row, call CCFXQuery::AddRow and use the return value as the row index for your call to SetData.

Parameters

Parameter | Description
iRow | Row of data element to set (1-based)
iColumn | Column of data element to set (1-based)
lpszData | New value for data element

Example

The following example shows the addition of two rows to a three-column ('City', 'State', and 'Zip') query:

// First row
int iRow ;
iRow = pQuery->AddRow() ;
pQuery->SetData( iCity, iRow, "Minneapolis" ) ;
pQuery->SetData( iState, iRow, "MN" ) ;
pQuery->SetData( iZip, iRow, "55345" ) ;

// Second row
iRow = pQuery->AddRow() ;
pQuery->SetData( iCity, iRow, "St. Paul" ) ;
pQuery->SetData( iState, iRow, "MN" ) ;
pQuery->SetData( iZip, iRow, "55105" ) ;


CCFXRequest class

Abstract class that represents a request made to a ColdFusion Extension (CFX). An instance of this class is passed to the main function of your extension DLL. The class provides interfaces that can be used by the custom extension for the following actions:

  • Reading and writing variables
  • Returning output
  • Creating and using queries
  • Throwing exceptions


Class members

virtual BOOL AttributeExists( LPCSTR lpszName ) | CCFXRequest::AttributeExists checks whether the attribute was passed to the tag.
virtual LPCSTR GetAttribute( LPCSTR lpszName ) | CCFXRequest::GetAttribute gets the value of the passed attribute.
virtual CCFXStringSet* GetAttributeList() | CCFXRequest::GetAttributeList gets an array of attribute names passed to the tag.
virtual CCFXQuery* GetQuery() | CCFXRequest::GetQuery gets the query that was passed to the tag.
virtual LPCSTR GetSetting( LPCSTR lpszSettingName ) | CCFXRequest::GetSetting This member is deprecated. Do not use it in new applications. It might not work, and might cause an error, in later releases.
virtual void Write( LPCSTR lpszOutput ) | CCFXRequest::Write writes text output back to the user.
virtual void SetVariable( LPCSTR lpszName, LPCSTR lpszValue ) | CCFXRequest::SetVariable sets a variable in the template that contains this tag.
virtual CCFXQuery* AddQuery( LPCSTR lpszName, CCFXStringSet* pColumns ) | CCFXRequest::AddQuery adds a query to the template that contains this tag.
virtual BOOL Debug() | CCFXRequest::Debug checks whether the tag contains the DEBUG attribute.
virtual void WriteDebug( LPCSTR lpszOutput ) | CCFXRequest::WriteDebug writes text output into the debug stream.
virtual CCFXStringSet* CreateStringSet() | CCFXRequest::CreateStringSet allocates and returns a CCFXStringSet instance.
virtual void ThrowException( LPCSTR lpszError, LPCSTR lpszDiagnostics ) | CCFXRequest::ThrowException throws an exception and ends processing of this request.
virtual void ReThrowException( CCFXException* e ) | CCFXRequest::ReThrowException re-throws an exception that has been caught.
virtual void SetCustomData( LPVOID lpvData ) | CCFXRequest::SetCustomData sets custom (tag specific) data to carry with a request.
virtual LPVOID GetCustomData() | CCFXRequest::GetCustomData gets custom (tag specific) data for a request.


CCFXRequest::AddQuery

Syntax

CCFXQuery* CCFXRequest::AddQuery(LPCSTR lpszName,
CCFXStringSet* pColumns)

Description

Adds a query to the calling template. The query can be accessed by CFML tags (for example, CFOUTPUT or CFTABLE) within the template. After calling AddQuery, the query is empty (it has 0 rows). To populate the query with data, call the CCFXQuery::AddRow and CCFXQuery::SetData functions.

Returns

Returns a pointer to the query that was added to the template (an object of class CCFXQuery). The memory allocated for the returned query is freed automatically by ColdFusion after the request is completed.

Parameters

Parameter | Description
lpszName | Name of query to add to the template (must be unique)
pColumns | List of column names to be used in the query

Example

The following example adds a query named 'People' to the calling template. The query has two columns ('FirstName' and 'LastName') and two rows:

// Create a string set and add the column names to it
CCFXStringSet* pColumns = pRequest->CreateStringSet() ;
int iFirstName = pColumns->AddString( "FirstName" ) ;
int iLastName = pColumns->AddString( "LastName" ) ;

// Create a query that contains these columns
CCFXQuery* pQuery = pRequest->AddQuery( "People", pColumns ) ;

// Add data to the query
int iRow ;
iRow = pQuery->AddRow() ;
pQuery->SetData( iRow, iFirstName, "John" ) ;
pQuery->SetData( iRow, iLastName, "Smith" ) ;
iRow = pQuery->AddRow() ;
pQuery->SetData( iRow, iFirstName, "Jane" ) ;
pQuery->SetData( iRow, iLastName, "Doe" ) ;


CCFXRequest::AttributeExists

Syntax

BOOL CCFXRequest::AttributeExists(LPCSTR lpszName)

Description

Checks whether the attribute was passed to the tag. Returns True if the attribute is available; False, otherwise.

Parameters

Parameter | Description
lpszName | Name of the attribute to check (case insensitive)

Example

The following example checks whether the user passed an attribute named DESTINATION to the tag, and throws an exception if the attribute was not passed:

if ( pRequest->AttributeExists("DESTINATION")==FALSE )
{
   pRequest->ThrowException(
      "Missing DESTINATION parameter",
      "You must pass a DESTINATION parameter in "
      "order for this tag to work correctly." ) ;
}


CCFXRequest::CreateStringSet

Syntax

CCFXStringSet* CCFXRequest::CreateStringSet(void)

Description

Allocates and returns an instance. Always use this function to create string sets, as opposed to directly using the 'new' operator.

Returns

Returns an object of CCFXStringSet Class. The memory allocated for the returned string set is freed automatically by ColdFusion after the request is completed

Example

The following example creates a string set and adds three strings to it:

CCFXStringSet* pColors = pRequest->CreateStringSet() ;
pColors->AddString( "Red" ) ;
pColors->AddString( "Green" ) ;
pColors->AddString( "Blue" ) ;


CCFXRequest::Debug

Syntax

BOOL CCFXRequest::Debug(void)

Description

Checks whether the tag contains the DEBUG attribute. Use this function to determine whether to write debug information for a request. For more information, see CCFXRequest::WriteDebug.

Returns

Returns True if the tag contains the DEBUG attribute; False, otherwise.

Example

The following example checks whether the DEBUG attribute is present, and if it is, it writes a brief debug message:

if ( pRequest->Debug() )
{
               pRequest->WriteDebug( "Top secret debug info" ) ;
}


CCFXRequest::GetAttribute

Syntax

LPCSTR CCFXRequest::GetAttribute(LPCSTR lpszName)

Description

Retrieves the value of the passed attribute. Returns an empty string if the attribute does not exist. (To test whether an attribute was passed to the tag, use CCFXRequest::AttributeExists.)

Returns

Returns the value of the attribute passed to the tag. If no attribute of that name was passed to the tag, an empty string is returned.

Parameters

Parameter | Description
lpszName | Name of the attribute to retrieve (case insensitive)

Example

The following example retrieves an attribute named DESTINATION and writes its value back to the user:

LPCSTR lpszDestination = pRequest->GetAttribute("DESTINATION") ;
pRequest->Write( "The destination is: " ) ;
pRequest->Write( lpszDestination ) ;


CCFXRequest::GetAttributeList

Syntax

CCFXStringSet* CCFXRequest::GetAttributeList(void)

Description

Gets an array of attribute names passed to the tag. To get the value of one attribute, use CCFXRequest::GetAttribute.

Returns

Returns an object of class CCFXStringSet Class that contains a list of attributes passed to the tag. The memory allocated for the returned string set is freed automatically by ColdFusion after the request is completed.

Example

The following example gets the list of attributes and iterates over the list, writing each attribute and its value back to the user.

LPCSTR lpszName, lpszValue ;
CCFXStringSet* pAttribs = pRequest->GetAttributeList() ;
int nNumAttribs = pAttribs->GetCount() ;

for( int i=1; i<=nNumAttribs; i++ )
{
               lpszName = pAttribs->GetString( i ) ;
               lpszValue = pRequest->GetAttribute( lpszName ) ;
               pRequest->Write( lpszName ) ;
               pRequest->Write( " = " ) ;
               pRequest->Write( lpszValue ) ;
               pRequest->Write( "<BR>" ) ;
}


CCFXRequest::GetCustomData

Syntax

LPVOID CCFXRequest::GetCustomData(void)

Description

Gets the custom (tag specific) data for the request. This member is typically used from within subroutines of a tag implementation to extract tag data from a request.

Returns

Returns a pointer to the custom data, or NULL if no custom data has been set during this request using CCFXRequest::SetCustomData.

Example

The following example retrieves a pointer to a request specific data structure of hypothetical type MYTAGDATA:

void DoSomeGruntWork( CCFXRequest* pRequest )
{
      MYTAGDATA* pTagData =
         (MYTAGDATA*)pRequest->GetCustomData() ;

      ... remainder of procedure ...
}


CCFXRequest::GetQuery

Syntax

CCFXQuery* CCFXRequest::GetQuery(void)

Description

Retrieves a query that was passed to a tag. To pass a query to a custom tag, you use the QUERY attribute. This attribute should be set to the name of a query (created using the CFQUERY tag or another custom tag). The QUERY attribute is optional and should be used only by tags that process an existing data set.

Returns

Returns an object of the CCFXQuery class that represents the query passed to the tag. If no query was passed to the tag, NULL is returned. The memory allocated for the returned query is freed automatically by ColdFusion after the request is completed.

Example

The following example retrieves the query that was passed to the tag. If no query was passed, an exception is thrown:

CCFXQuery* pQuery = pRequest->GetQuery() ;
if ( pQuery == NULL )
{
               pRequest->ThrowException(
                  "Missing QUERY parameter",
                  "You must pass a QUERY parameter in "
                  "order for this tag to work correctly." ) ;
}


CCFXRequest::ReThrowException

Syntax

void CCFXRequest::ReThrowException(CCFXException* e)

Description

Re-throws an exception that has been caught within an extension procedure. This function is used to avoid having C++ exceptions that are thrown by DLL extension code propagate back into ColdFusion. Catch ALL C++ exceptions that occur in extension code, and either re-throw them (if they are of the CCFXException class) or create and throw a new exception pointer using CCFXRequest::ThrowException.

Parameters

Parameter | Description
e | A CCFXException that has been caught

Example

The following code demonstrates how to handle exceptions in ColdFusion Extension DLL procedures:

try
{
               ...Code that could throw an exception...
}
catch( CCFXException* e )
{
               ...Do appropriate resource cleanup here...
               // Re-throw the exception
               pRequest->ReThrowException( e ) ;
}
catch( ... )
{
               // Something nasty happened

               pRequest->ThrowException(
               "Unexpected error occurred in CFX tag", "" ) ;
}


CCFXRequest::SetCustomData

Syntax

void CCFXRequest::SetCustomData(LPVOID lpvData)

Description

Sets custom (tag specific) data to carry with the request. Use this function to store request specific data to pass to procedures within your custom tag implementation.

Parameters

Parameter | Description
lpvData | Pointer to custom data

Example

The following example creates a request-specific data structure of hypothetical type MYTAGDATA and stores a pointer to the structure in the request for future use:

void ProcessTagRequest( CCFXRequest* pRequest )
      try
      {
               MYTAGDATA tagData ;
               pRequest->SetCustomData( (LPVOID)&tagData ) ;

               ... remainder of procedure ...
}


CCFXRequest::SetVariable

Syntax

void CCFXRequest::SetVariable(LPCSTR lpszName, LPCSTR lpszValue)

Description

Sets a variable in the calling template. If the variable name already exists in the template, its value is replaced. If it does not exist, a variable is created. The values of variables created using SetVariable can be accessed in the same manner as other template variables (e.g., #MessageSent#).

Parameters

Parameter | Description
lpszName | Name of variable
lpszValue | Value of variable

Example

The following example sets the value of a variable named 'MessageSent' based on the success of an operation performed by the custom tag:

BOOL bMessageSent;
...attempt to send the message...
if ( bMessageSent == TRUE )
{
               pRequest->SetVariable( "MessageSent", "Yes" ) ;
}
else
{
               pRequest->SetVariable( "MessageSent", "No" ) ;
}


CCFXRequest::ThrowException

Syntax

void CCFXRequest::ThrowException(LPCSTR lpszError,
LPCSTR lpszDiagnostics)

Description

Throws an exception and ends processing of a request. Call this function when you encounter an error that does not allow you to continue processing the request. This function is almost always combined with the CCFXRequest::ReThrowException to protect against resource leaks in extension code.

Parameters

Parameter | Description
lpszError | Short identifier for error
lpszDiagnostics | Error diagnostic information

Example

The following example throws an exception indicating that an unexpected error occurred while processing a request:

char buffError[512] ;
wsprintf( buffError,
      "Unexpected Windows NT error number %ld "
      "occurred while processing request.", GetLastError() ) ;

pRequest->ThrowException( "Error occurred", buffError ) ;


CCFXRequest::Write

Syntax

void CCFXRequest::Write(LPCSTR lpszOutput)

Description

Writes text output back to the user.

Parameters

Parameter | Description
lpszOutput | Text to output

Example

The following example creates a buffer to hold an output string, fills the buffer with data, and writes the output back to the user:

CHAR buffOutput[1024] ;
wsprintf( buffOutput, "The destination is: %s",
      pRequest->GetAttribute("DESTINATION") ) ;
pRequest->Write( buffOutput ) ;


CCFXRequest::WriteDebug

Syntax

void CCFXRequest::WriteDebug(LPCSTR lpszOutput)

Description

Writes text output into the debug stream. The text is only displayed to the end-user if the tag contains the DEBUG attribute. (For more information, see CCFXRequest::Debug.)

Parameters

Parameter | Description
lpszOutput | Text to output

Example

The following example checks whether the DEBUG attribute is present; if so, it writes a brief debug message:

if ( pRequest->Debug() )
{
               pRequest->WriteDebug( "Top secret debug info" ) ;
}


CCFXStringSet Class

Abstract class that represents a set of ordered strings. Strings can be added to a set and can be retrieved by a numeric index (index values for strings are 1-based). To create a string set, use CCFXRequest::CreateStringSet.


Class members

virtual int AddString( LPCSTR lpszString ) | CCFXStringSet::AddString adds a string to the end of a list.
virtual int GetCount() | CCFXStringSet::GetCount gets the number of strings contained in a list.
virtual LPCSTR GetString( int iIndex ) | CCFXStringSet::GetString gets the string located at the passed index.
virtual int GetIndexForString( LPCSTR lpszString ) | CCFXStringSet::GetIndexForString gets the index for the passed string.


CCFXStringSet::AddString

Syntax

int CCFXStringSet::AddString(LPCSTR lpszString)

Description

Adds a string to the end of the list.

Returns

The index of the string that was added.

Parameters

Parameter | Description
lpszString | String to add to the list

Example

The following example demonstrates adding three strings to a string set and saving the indexes of the items that are added:

CCFXStringSet* pSet = pRequest->CreateStringSet() ;
int iRed = pSet->AddString( "Red" ) ;
int iGreen = pSet->AddString( "Green" ) ;
int iBlue = pSet->AddString( "Blue" ) ;


CCFXStringSet::GetCount

Syntax

int CCFXStringSet::GetCount(void)

Description

Gets the number of strings in a string set. The value can be used with CCFXStringSet::GetString to iterate over the strings in the set (recall that the index values for strings in the list begin at 1).

Returns

Returns the number of strings contained in the string set.

Example

The following example demonstrates using GetCount with CCFXStringSet::GetString to iterate over a string set and write the contents of the list back to the user:

int nNumItems = pStringSet->GetCount() ;
for ( int i=1; i<=nNumItems; i++ )
{
               pRequest->Write( pStringSet->GetString( i ) ) ;
               pRequest->Write( "<BR>" ) ;
}


CCFXStringSet::GetIndexForString

Syntax

int CCFXStringSet::GetIndexForString(LPCSTR lpszString)

Description

Searches for a passed string. The search is case-insensitive.

Returns

If the string is found, its index within the string set is returned. If it is not found, the constant CFX_STRING_NOT_FOUND is returned.

Parameters

Parameter | Description
lpszString | String to search for

Example

The following example demonstrates a search for a string and throwing an exception if it is not found:

CCFXStringSet* pAttribs = pRequest->GetAttributeList() ;

int iDestination =
      pAttribs->GetIndexForString("DESTINATION") ;
if ( iDestination == CFX_STRING_NOT_FOUND )
{
               pRequest->ThrowException(
               "DESTINATION attribute not found."
               "The DESTINATION attribute is required "
               "by this tag." ) ;
}


CCFXStringSet::GetString

Syntax

LPCSTR CCFXStringSet::GetString(int iIndex)

Description

Retrieves the string located at the passed index (index values are 1-based).

Returns

Returns the string located at the passed index.

Parameters

Parameter | Description
iIndex | Index of string to retrieve

Example

The following example demonstrates GetString with CCFXStringSet::GetCount to iterate over a string set and write the contents of a list back to the user:

int nNumItems = pStringSet->GetCount() ;
for ( int i=1; i<=nNumItems; i++ )
{
               pRequest->Write( pStringSet->GetString( i ) ) ;
               pRequest->Write( "<BR>" ) ;
}

Previous


ColdFusion Java CFX Reference

This chapter describes the Java interfaces available for building ColdFusion custom CFXs in Java.

Contents
  • Overview class libraries
  • CustomTag Interface
  • Query Interface
  • Request Interface
  • Response Interface
  • Debugging Classes Reference
Next


Overview class libraries

The following Java interfaces are available for building ColdFusion custom CFXs in Java.

Interface | Methods
CustomTag Interface | processRequest
Query Interface | addRow getColumnIndex getColumns getData getName getRowCount setData
Request Interface | attributeExists debug getAttribute getAttributeList getIntAttribute getQuery getSetting
Response Interface |


CustomTag Interface

public abstract interface CustomTag

Interface for implementing custom tags.

Classes that implement this interface can be specified in the CLASS attribute of the Java CFX tag. For example, in a class MyCustomTag, which implements this interface, the following CFML code calls the MyCustomTag.processRequest method:

<CFX_MyCustomTag>

Other attributes can be passed to the Java CFX tag. Their values are available using the Request object passed to the processRequest method.


Methods

Returns
Syntax
Description
void

processRequest(Request request,
   Response response)
Processes a request originating from the CFX_mycustomtag tag


processRequest

Description

Processes a request originating from the Java CFX tag.

Category

CustomTag Interface

Syntax

public void processRequest(Request request, Response response)

Throws

Exception If an unexpected error occurs while processing the request.

Parameters

Parameter | Description
request | Parameters (attributes, query, and so on.) for this request
response | Interface for generating response to request (output, variables, queries, and so on.)


Query Interface

public abstract interface Query

Interface to a query used or created by a CustomTag. A query contains tabular data organized by named columns and rows.


Methods

Returns
Method
Description
int

addRow()
Adds a row to the query
int

getColumnIndex(String name)
Gets the index of a column given its name
String[]

getColumns()
Gets a list of the column names in a query
String

getData(int iRow, int iCol)
Gets a data element from a row and column of a query.
String

getName()
Gets the name of a query
int

getRowCount()
Gets the number of rows in a query
void

setData(int iRow, int iCol,
   String data)
Sets a data element in a row and column of a query.


addRow

Description

Adds a row to a query. Call this method to append a row to a query.

Returns the index of the row that was appended to the query.

Category

Query Interface

Syntax

public int addRow()

See also

setData , getData

Example

The following example demonstrates the addition of two rows to a query that has three columns, 'City', 'State', and 'Zip':

// Define column indexes
int iCity = 1, iState = 2, iZip = 3 ;

// First row
int iRow = query.addRow() ;
query.setData( iRow, iCity, "Minneapolis" ) ;
query.setData( iRow, iState, "MN" ) ;
query.setData( iRow, iZip, "55345" ) ;
// Second row
iRow = query.addRow() ;
query.setData( iRow, iCity, "St. Paul" ) ;
query.setData( iRow, iState, "MN" ) ;
query.setData( iRow, iZip, "55105" ) ;


getColumnIndex

Description

Returns the index of the column, or -1 if no such column exists.

Category

Query Interface

Syntax

public int getColumnIndex(String name)

See also

getColumns, getData

Parameters

Parameter | Description
name | Name of column to get index of (lookup is case insensitive)

Example

The following example retrieves the index of the EMAIL column and uses it to output a list of the addresses contained in the column:

// Get the index of the EMAIL column
int iEMail = query.getColumnIndex( "EMAIL" ) ;

// Iterate over the query and output list of addresses
int nRows = query.getRowCount() ;
for( int iRow = 1; iRow <= nRows; iRow++ )
{
   response.write( query.getData( iRow, iEMail ) + "<BR>" ) ;
}


getColumns

Description

Returns an array of strings containing the names of the columns in the query.

Category

Query Interface

Syntax

public String[] getColumns()

Example

The following example retrieves the array of columns, then iterates over the list, writing each column name back to the user:

// Get the list of columns from the query
String[] columns = query.getColumns() ;
int nNumColumns = columns.length ;

// Print the list of columns to the user
response.write( "Columns in query: " ) ;
for( int i=0; i<nNumColumns; i++ )
{
   response.write( columns[i] + " " ) ;
}


getData

Description

Retrieves a data element from a row and column of a query. Row and column indexes begin with 1. You can find the number of rows in a query by calling getRowCount. You can find the number of columns in a query by calling getColumns.

Returns the value of the requested data element.

Category

Query Interface

Syntax

public String getData(int iRow, int iCol)

Throws

IndexOutOfBoundsException If an invalid index is passed to the method

See also

setData, addRow

Parameters

Parameter | Description
iRow | Row to retrieve data from (1-based)
iCol | Column to retrieve data from (1-based)

Example

The following example iterates over the rows of a query and writes the data back to the user in a simple, space-delimited format:

int iRow, iCol ;
int nNumCols = query.getColumns().length ;
int nNumRows = query.getRowCount() ;
for ( iRow = 1; iRow <= nNumRows; iRow++ )
{
   for ( iCol = 1; iCol <= nNumCols; iCol++ )
   {
      response.write( query.getData( iRow, iCol ) + " " ) ;
   }
   response.write( "<BR>" ) ;
}


getName

Description

Returns the name of a query.

Category

Query Interface

Syntax

public String getName()

Example

The following example retrieves the name of a query and writes it back to the user:

Query query = request.getQuery() ;
   response.write( "The query name is: " + query.getName() ) ;


getRowCount

Description

Retrieves the number of rows in a query.

Returns the number of rows contained in a query.

Category

Query Interface

Syntax

public int getRowCount()

Example

The following example retrieves the number of rows in a query and writes it back to the user:

Query query = request.getQuery() ;
   int rows = query.getRowCount() ;
   response.write( "The number of rows in the query is "
   + Integer.toString(rows) ) ;


setData

Description

Sets a data element in a row and column of a query. Row and column indexes begin with 1. Before calling setData for a given row, call addRow and use the return value as the row index for your call to setData.

Category

Query Interface

Syntax

public void setData(int iRow, int iCol, String data)

Throws

IndexOutOfBoundsException If an invalid index is passed to the method

See also

getData , addRow

Parameters

Parameter | Description
iRow | Row of data element to set (1-based)
iCol | Column of data element to set (1-based)
data | New value for data element

Example

The following example demonstrates the addition of two rows to a query that has three columns, 'City', 'State', and 'Zip':

// Define column indexes
int iCity = 1, iState = 2, iZip = 3 ;

// First row
int iRow = query.addRow() ;
query.setData( iRow, iCity, "Minneapolis" ) ;
query.setData( iRow, iState, "MN" ) ;
query.setData( iRow, iZip, "55345" ) ;

// Second row
iRow = query.addRow() ;
query.setData( iRow, iCity, "St. Paul" ) ;
query.setData( iRow, iState, "MN" ) ;
query.setData( iRow, iZip, "55105" ) ;


Request Interface

public abstract interface Request

Interface to a request made to a CustomTag. The interface includes methods for retrieving attributes passed to the tag (including queries) and reading global tag settings.


Methods

Returns
Syntax
Description
boolean

attributeExists(String name)
Checks whether the attribute was passed to this tag.
boolean

debug()
Checks whether the tag contains the DEBUG attribute.
String

getAttribute(String name)
Retrieves the value of the passed attribute.
String

getAttributeList()
Retrieves a list of attributes passed to the tag.
int

getIntAttribute(String name)
Retrieves the value of the passed attribute as an integer.
int

getIntAttribute(String name,
   int def)
Retrieves the value of the passed attribute as an integer (returns default if the attribute does not exist or is not a valid number).
Query

getQuery()
Retrieves the query that was passed to this tag.


attributeExists

Description

Checks whether the attribute was passed to this tag.

Returns true if the attribute is available, otherwise returns false.

Category

Request Interface

Syntax

public boolean attributeExists(String name)

See also

getAttribute , getAttributeList

Parameters

Parameter | Description
name | Name of the attribute to check (case insensitive)

Example

The following example checks whether the user passed an attribute named DESTINATION to the tag; if not, it throws an exception:

if ( ! request.attributeExists("DESTINATION") )
{
   throw new Exception(
   "Missing DESTINATION parameter",
   "You must pass a DESTINATION parameter in "
   "order for this tag to work correctly." ) ;
} ;


debug

Description

Checks whether the tag contains the DEBUG attribute. Use this method to determine whether to write debug information for this request. For more information, see writeDebug.

Returns true if the tag contains the DEBUG attribute otherwise returns false.

Category

Request Interface

Syntax

public boolean debug()

See also

writeDebug

Example

The following example checks whether the DEBUG attribute is present, and if so, it writes a brief debug message:

if ( request.debug() )
{
   response.writeDebug( "debug info" ) ;
}


getAttribute

Description

Retrieves the value of a passed attribute. Returns an empty string if the attribute does not exist (use attributeExists to test whether an attribute was passed to the tag). Use getAttribute(String,String) to return a default value rather than an empty string.

Returns the value of the attribute passed to the tag. If no attribute of that name was passed to the tag, an empty string is returned.

Category

Request Interface

Syntax

public String getAttribute(String name)

See also

attributeExists , getAttributeList , getIntAttribute , getAttribute

Parameters

Parameter | Description
name | The attribute to retrieve (case insensitive)

Example

The following example retrieves an attribute named DESTINATION and writes its value back to the user:

String strDestination = request.getAttribute("DESTINATION") ;
response.write( "The destination is: " + strDestination ) ;


getAttributeList

Description

Retrieves a list of attributes passed to the tag. To retrieve the value of one attribute, use the getAttribute member function.

Returns an array of strings containing the names of the attributes passed to the tag.

Category

Request Interface

Syntax

public String[] getAttributeList()

See also

attributeExists, getAttributeList

Example

The following example retrieves the list of attributes, then iterates over the list, writing each attribute and its value back to the user:

String[] attribs = request.getAttributeList() ;
int nNumAttribs = attribs.length ;

for( int i = 0; i < nNumAttribs; i++ )
{
   String strName = attribs[i] ;
   String strValue = request.getAttribute( strName ) ;
   response.write( strName + "=" + strValue + "<BR>" ) ;
}


getIntAttribute

Description

Retrieves the value of the passed attribute as an integer. Returns -1 if the attribute does not exist. Use attributeExists to test whether an attribute was passed to the tag. Use getIntAttribute(String,int) to return a default value rather than throwing an exception or returning -1.

Returns the value of the attribute passed to the tag. If no attribute of that name was passed to the tag, -1 is returned.

Category

Request Interface

Syntax

public int getIntAttribute(String name)

Throws

NumberFormatException If the attribute is not a valid number.

See also

attributeExists, getAttributeList, getIntAttribute

Parameters

Parameter | Description
name | The attribute to retrieve (case insensitive)

Example

The following example retrieves an attribute named PORT and writes its value back to the user:

int nPort = request.getIntAttribute("PORT") ;
if ( nPort != -1 )
   response.write( "The port is: " + String.valueOf(nPort) ) ;


getQuery

Description

Retrieves the query that was passed to this tag.

To pass a query to a custom tag, you use the QUERY attribute. It should be set to the name of a query (created using the cfquery tag). The QUERY attribute is optional and should be used only by tags that process an existing dataset.

Returns the Query that was passed to the tag. If no query was passed, returns null.

Category

Request Interface

Syntax

public Query getQuery()

Example

The following example retrieves a query that was passed to a tag. If no query was passed, an exception is thrown:

Query query = request.getQuery() ;
if ( query == null )
{
   throw new Exception(
   "Missing QUERY parameter. " +
   "You must pass a QUERY parameter in "
   "order for this tag to work correctly." ) ;
}


getSetting

Description

Retrieves the value of a global custom tag setting. Custom tag settings are stored in the CustomTags section of the ColdFusion Registry key.

Returns the value of the custom tag setting. If no setting of that name exists, an empty string is returned.

Category

Request Interface

Syntax

public String getSetting(String name)

Parameters

Parameter | Description
name | The name of the setting to retrieve (case insensitive)

Usage

All custom tags implemented in Java share a registry key for storing settings. To avoid name conflicts, preface the names of settings with the name of your CustomTag class. For example, the code below retrieves the value of a setting named 'VerifyAddress' for a CustomTag class named MyCustomTag:

String strVerify = request.getSetting("MyCustomTag.VerifyAddress") ;
if ( Boolean.valueOf(strVerify) )
{
   // Do address verification...
}


Response Interface

public abstract interface Response

Interface to response generated from a CustomTag. This interface includes methods for writing output, generating queries, and setting variables in the calling page.


Methods

Returns
Syntax
Description
Query

addQuery(String name, String[] columns)
Adds a query to the calling template.
void

setVariable(String name, String value)
Sets a variable in the calling template.
void

write(String output)
Outputs text back to the user.
void

writeDebug(String output)
Writes text output into the debug stream.


addQuery

Description

Adds a query to the calling template. The query can be accessed by CFML tags in the template. After calling addQuery, the query is empty (it has 0 rows). To populate the query with data, call the Query member functions addRow and setData.

Returns the Query that was added to the template.

Category

Response Interface

Syntax

public Query addQuery(String name, String[] columns)

Throws

IllegalArgumentException - if the name parameter is not a valid CFML variable name

See also

addRow, setData

Parameters

Parameter | Description
name | The name of the query to add to the template
columns | The column names to use in the query

Example

The following example adds a Query named 'People' to the calling template. The query has two columns ('FirstName' and 'LastName') and two rows:

// Create string array with column names (also track columns indexes)
String[] columns = { "FirstName", "LastName" } ;
int iFirstName = 1, iLastName = 2 ;

// Create a query which contains these columns
Query query = response.addQuery( "People", columns ) ;

// Add data to the query
int iRow = query.addRow() ;
query.setData( iRow, iFirstName, "John" ) ;
query.setData( iRow, iLastName, "Smith" ) ;
iRow = query.addRow() ;
query.setData( iRow, iFirstName, "Jane" ) ;
query.setData( iRow, iLastName, "Doe" ) ;


setVariable

Description

Sets a variable in the calling template. If the variable name specified exists in the template, its value is replaced. If it does not exist, a new variable is created.

Category

Response Interface

Syntax

public void setVariable(String name, String value)

Throws

IllegalArgumentException If the name parameter is not a valid CFML variable name

Parameters

Parameter | Description
name | The name of the variable to set
value | The value to set the variable to

Example

For example, this code sets the value of a variable named 'MessageSent' based on the success of an operation performed by the custom tag:

boolean bMessageSent ;

   ...attempt to send the message...

   if ( bMessageSent == true )
   {
      response.setVariable( "MessageSent", "Yes" ) ;
   }
   else
   {
      response.setVariable( "MessageSent", "No" ) ;
   }


write

Description

Outputs text back to the user.

Category

Response Interface

Syntax

public void write(String output)

Parameters

Parameter | Description
output | Text to output

Example

The following example outputs the value of the DESTINATION attribute:

response.write( "DESTINATION = " +
   request.getAttribute("DESTINATION") ) ;


writeDebug

Description

Writes text output into the debug stream. This text is displayed to the end-user only if the tag contains the DEBUG attribute (check for this attribute using the Request.debug member function).

Category

Response Interface

Syntax

public void writeDebug(String output)

See also

debug

Parameters

Parameter | Description
output | The text to output

Example

The following example checks whether the DEBUG attribute is present; if so, it writes a brief debug message:

if ( request.debug() )
{
   response.writeDebug( "debug info" ) ;
}


Debugging Classes Reference

The constructors and methods supported by the DebugRequest, DebugResponse, and DebugQuery classes are as follows. These classes also support the other methods of the Request, Response, and Query interfaces, respectively.


DebugRequest

// initialize a debug request with attributes
public DebugRequest( Hashtable attributes ) ;

// initialize a debug request with attributes and a query
public DebugRequest( Hashtable attributes, Query query ) ;

// initialize a debug request with attributes, a query, and settings
public DebugRequest( Hashtable attributes, Query query,
                     Hashtable settings ) ;


DebugResponse

// initialize a debug response
public DebugResponse() ;

// print the results of processing
public void printResults() ;


DebugQuery

// initialize a query with name and columns
public DebugQuery( String name, String[] columns )
   throws IllegalArgumentException ;

// initialize a query with name, columns, and data
public DebugQuery( String name, String[] columns, String[][] data )
   throws IllegalArgumentException ;

Previous


WDDX JavaScript Objects

This chapter provides information about JavaScript objects and functions used to WDDX in a ColdFusion application.

Contents
  • JavaScript object overview
  • WddxSerializer object
  • WddxRecordset object
Next


JavaScript object overview

These are the JavaScript objects and functions.

Class | Members
WddxSerializer object | serialize serializeVariable serializeValue write
WddxRecordset object | addColumn addRows getField getRowCount setField wddxSerialize

WDDX JavaScript objects are defined in the wddx.js file; this file is installed in the webroot/cfide/scripts directory.

To use these objects, you must put a JavaScript tag before the code that refers to the objects; for example:

<script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script>


WddxSerializer object

The WddxSerializer object includes functions that serialize any JavaScript data structure.


Functions

The only function that developers typically call is serialize.

Function Syntax | Description
object.serialize(rootobj) | Creates a WDDX packet for a passed WddxRecordset instance.
object.serializeVariable(name, obj) | Serializes a property of a structure. If an object is not a string, number, array, Boolean, or a date, WddxSerializer treats it as a structure.
object.serializeValue(obj) | Recursively serializes eligible data in a passed instance.
object.write(str) | Appends data to the serialized data stream.


serialize

Description

Creates a WDDX packet for a passed WddxRecordset instance.

Syntax

object.serialize( rootobj )

Parameters

Parameter | Description
object | Instance name of the WddxSerializer object
rootobj | JavaScript data structure to serialize

Return value

Returns a serialized WDDX packet as a String if the function succeeds, or a null value if an error occurs.

Usage

Call this function to serialize the data in a WddxRecordset instance.

Example

This example shows a JavaScript function that you can call to serialize a WddxRecordset instance. It copies serialized data to a form field for display:

function serializeData(data, formField)
{
   wddxSerializer = new WddxSerializer();
   wddxPacket = wddxSerializer.serialize(data);

   if (wddxPacket != null)
   {
      formField.value = wddxPacket;
   }
   else
   {
      alert("Couldn't serialize data");
   }
}


serializeVariable

Description

Serializes a property of a structure. If an object is not a string, number, array, Boolean, or date, WddxSerializer treats it as a structure.

Syntax

object.serializeVariable( name, obj )

Parameters

Parameter | Description
object | Instance name of a WddxSerializer object
name | Property to serialize
obj | Instance name of the value to serialize

Return value

Returns a Boolean True if serialization was successful, or False if an error occurs.

Usage

This is an internal function; you do not typically call it.

Example

This example is from the WddxSerializer serializeValue function:

...
// Some generic object; treat it as a structure
   this.write("<struct>");
   for (prop in obj)
   {
      bSuccess = this.serializeVariable(prop, obj[prop]);
      if (! bSuccess)
      {
         break;
      }
   }
   this.write("</struct>");
...


serializeValue

Description

Recursively serializes eligible data in a passed instance. Eligible data includes:

  • String
  • Number
  • Boolean
  • Date
  • Array
  • Recordset
  • Any JavaScript object

This function serializes null values as empty strings.

Syntax

object.serializeValue( obj )

Parameters

Parameter | Description
object | Instance name of the WddxSerializer object
obj | Instance name of the WddxRecordset object to serialize

Return value

Returns a Boolean True if obj was serialized successfully; or False if an error occurs.

Usage

This is an internal function; you do not typically call it.

Example

This example is from the WddxSerializer serialize function:

...
this.wddxPacket = "";
this.write("<wddxPacket version='1.0'><header/><data>");
bSuccess = this.serializeValue(rootObj);
this.write("</data></wddxPacket>");
if (bSuccess)
{
   return this.wddxPacket;
}
else
{
   return null;
}
...


write

Description

Appends data to a serialized data stream.

Syntax

object.write( str )

Parameters

Parameter | Description
object | Instance name of the WddxSerializer object
str | String to be copied to the serialized data stream

Return value

Returns an updated serialized data stream as a String.

Usage

This is an internal function; you do not typically call it.

Example

This example is from the WddxSerializer serializeValue function:

...
else if (typeof(obj) == "number")
{
   // Number value
   this.write("<number>" + obj + "</number>");
}
else if (typeof(obj) == "boolean")
{
   // Boolean value
   this.write("<boolean value='" + obj + "'/>");
}
...


WddxRecordset object

Includes functions that you call as needed when constructing a WDDX record set.


Functions

Function syntax | Description
object.addColumn(name) | Adds a column to all rows in a WddxRecordset instance.
object.addRows(n) | Adds rows to all columns in a WddxRecordset instance.
object.dump(escapeStrings) | Displays WddxRecordset object data.
object.getField(row, col) | Returns the element in a row/column position.
object.getRowCount() | Indicates the number of rows in a WddxRecordset instance.
object.setField(row, col, value) | Sets the element in a row/column position.
object.wddxSerialize(serializer) | Serializes a record set.

:

Return value

HTML table of the WddxRecordset object data.

Usage

Convenient for debugging and testing record sets. The boolean parameter escapeStrings determines whether <>& characters in string values are escaped as &lt;&gt;&amp; in HTML.

Example

<!--- Create a simple query --->
<cfquery name = "q" datasource ="cfsnippets">
SELECT Message_Id, Thread_id, Username, Posted
FROM messages
</cfquery>
<!--- Load the wddx.js file, which includes the dump function --->
<script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script>
<script>
// Use WDDX to move from CFML data to JS
<cfwddx action="cfml2js" input="#q#" topLevelVariable="qj">
// Dump the record set
document.write(qj.dump(true));
</script>


addColumn

Description

Adds a column to all rows in a WddxRecordset instance.

Syntax

object.addColumn( name )

Parameters

Parameter | Description
object | Instance name of the WddxRecordset object
name | Name of the column to add

Return value

None.

Usage

Adds a column to every row of the WDDX record set. Initially the new column’s values are set to NULL.

Example

This example calls the addColumn function:

// create a new record set
rs = new WddxRecordset();

// add a new column
rs.addColumn("NewColumn");

// extend the record set by 3 rows
rs.addRows(3);

// set an element in the first row
// newValue is a previously defined variable
rs.setField(0, "NewColumn", newValue);


addRows

Description

Adds rows to all columns in a WddxRecordset instance.

Syntax

object.addRows( n )

Parameters

Parameter | Description
object | Instance name of the WddxRecordset object
n | Integer; number of rows to add

Return value

None.

Usage

This function adds the specified number of rows to every column of a WDDX record set. Initially, the row/column values are set to NULL.

Example

This example calls the addRows function:

// create a new record set
rs = new WddxRecordset();

// add a new column
rs.addColumn("NewColumn");

// extend the record set by 3 rows
rs.addRows(3);

// set an element in the first row
// newValue is a previously defined variable
rs.setField(0, "NewColumn", newValue);


getField

Description

Returns the element in the specified row/column position.

Syntax

object.getField( row, col )

Parameters

Parameter | Description
object | Instance name of the WddxRecordset object
row | Integer; zero-based row number of the value to return
col | Integer or string; column of the value to be returned.

Return value

Returns the value in the specified row/column position.

Usage

Call this function to access a value in a WDDX record set.

Example

This example calls the getField function (the variable r is a reference to a WddxRecordset instance):

for (row = 0; row < nRows; ++row)
{
   o += "<tr>";
   for (i = 0; i < colNames.length; ++i)
   {
      o += "<td>" + r.getField(row, colNames[i]) + "</td>";
   }
   o += "</tr>";
}


getRowCount

Description

Indicates the number of rows in a WddxRecordset instance.

Syntax

object.getRowCount( )

Parameters

Parameter | Description
object | Instance name of a WddxRecordset object

Return value

Integer. Returns the number of rows in the WddxRecordset instance.

Usage

Call this function before a looping construct to determine the number of rows in a record set.

Example

This example calls the getRowCount function:

function dumpWddxRecordset(r)
{
// Get row count
   nRows = r.getRowCount();
...
   for (row = 0; row < nRows; ++row)
...


setField

Description

Sets the element in the specified row/column position.

Syntax

object.setField( row, col, value )

Parameters

Parameter | Description
object | Instance name of a WddxRecordset object
row | Integer; row that contains the element to set
col | Integer or string; the column containing the element to set
value | Value to set

Return value

None.

Usage

Call this function to set a value in a WddxRecordset instance.

Example

This example calls the setField function:

// create a new recordset
rs = new WddxRecordset();

// add a new column
rs.addColumn("NewColumn");

// extend the record set by 3 rows
rs.addRows(3);

// set an element in the first row
// newValue is a previously defined variable
rs.setField(0, "NewColumn", newValue);


wddxSerialize

Description

Serializes a record set.

Syntax

object.wddxSerialize( serializer )

Parameters

Parameter | Description
object | Instance name of the WddxRecordset object
serializer | WddxSerializer instance

Return value

Returns a Boolean True if serialization was successful; or False if an error occurs.

Usage

This is an internal function; you do not typically call it.

Example

This example is from the WddxSerializer serializeValue function:

...
else if (typeof(obj) == "object")
{
if (obj == null)
{
// Null values become empty strings
this.write("<string></string>");
}
else if (typeof(obj.wddxSerialize) == "function")
{
// Object knows how to serialize itself
bSuccess = obj.wddxSerialize(this);
}
...

Previous


About This Book

Developing ColdFusion Applications provides the tools needed to develop Internet applications using ColdFusion. This book is intended for Web application programmers who are learning ColdFusion or wish to extended their ColdFusion programming knowledge. It provides a solid grounding in the tools that ColdFusion provides to develop Web applications.

Because of the power and flexibility of ColdFusion, you can create many different types of Web applications of varying complexity. As you become more familiar with the material presented in this manual, and begin to develop your own applications, you will want to refer to the CFML Reference for details about various tags and functions.

Contents
  • Using this book
  • Developer resources
  • About ColdFusion documentation
  • Getting answers
  • Contacting Macromedia
Next


Using this book

This book can to help anyone with a basic understanding of HTML learn to develop ColdFusion. However, this book is most useful if you have basic ColdFusion experience, or have read Getting Started Building ColdFusion MX Applications. The Getting Started book provides an introduction to ColdFusion and helps you develop the basic knowledge that will make using this book easier.


Book structure and contents

The book is divided into seven parts, as follows:

Part | Description
The CFML Programming Language | The Elements of CFML including variables, expressions, dynamic code, CFScript, and regular expressions.
Reusing CFML Code | Techniques for writing code once and using it many times, including the cfinclude tag, user-defined functions, custom CFML tags, ColdFusion components, and CFXAPI tags.
Developing CFML Applications | How to develop a complete ColdFusion application. Includes information on error handling, sharing data, locking code, securing access, internationalization, debugging, and troubleshooting.
Accessing and Using Data | Methods for accessing and using data sources, including an introduction to SQL and information on using SQL data bases, LADP directory services, and the Verity search engine
Requesting and Presenting Information | How to dynamically request information from users and display results on the user’s browser, including graphing data and providing data to Flash clients.
Using Web Elements and External Objects | How to use XML, Java objects including Enterprise JavaBeans, JSP pages, web services (including creating web services in ColdFusion), and COM and CORBA objects.
Using External Resources | Methods for getting and sending e-mail, accessing remote servers using HTTP and FTP, and accessing files and directories.

Each chapter includes basic information plus detailed coverage of the topic that should be of use to experienced ColdFusion developers.


Approaches to using this book

This section describes approaches to using this book for beginning ColdFusion developers, developers with some experience who want to develop expertise, and advanced developers who want to learn about the new and enhanced features of ColdFusion MX.


Beginning with ColdFusion

If you learning ColdFusion, a path such as the following might be most effective:

  1. Introduction to ColdFusion MX through Using Expressions and Pound Signs to learn the basics of the XML language.
  2. Introduction to Databases and SQL through Updating Your Database to learn about using database.s
  3. Retrieving and Formatting Data and Building Dynamic Forms to learn about requesting data from users.

    4. A this point, you should have a basic understanding of the basic elements of ColdFusion and can create simple ColdFusion applications. To learn to produce more complete and robust applications, you could proceed with the following chapters

  4. Designing and Optimizing a ColdFusion Application through Debugging and Troubleshooting Applications to learn how to build a complete ColdFusion application.
  5. Using Query of Queries to learn how to use queries effectively.
  6. Using Arrays and Structures through Building and Using ColdFusion Components to learn to use more advanced features of CFML, including ways to reuse code.

You can then read the remaining chapters as you add new features to your ColdFusion application.


Developing an in-depth knowledge of ColdFusion

If you have a basic understanding of ColdFusion as presented in Getting Started Building ColdFusion MX Applications or the Fast Track to ColdFusion course, you might want to start at Chapter 1 and work through to the end of the book, skipping any specialized chapters that you are unlikely to need.


Learning about new and modified ColdFusion features

If you are an advanced ColdFusion developer, you might want to learn about new or changed ColdFusion MX features. In this case, you start with Migrating ColdFusion 5 Applications; then read selected chapters in this book. The following chapters document features that are new or substantially enhanced in ColdFusion MX:

  • Writing and Calling User-Defined Functions
  • Building and Using ColdFusion Components
  • Securing Applications
  • Developing Globalized Applications
  • Debugging and Troubleshooting Applications
  • Charting and Graphing Data
  • Using the Flash Remoting service
  • Using XML and WDDX
  • Using Web Services
  • Integrating J2EE and Java Elements in CFML Applications

Nearly all chapters contain information that is new in ColdFusion MX, so you should also review all other chapters for useful information. The index and the table of contents are useful tools for finding new features or changed documentation.


Developer resources

Macromedia, Inc. is committed to setting the standard for customer support in developer education, documentation, technical support, and professional services. The Macromedia website is designed to give you quick access to the entire range of online resources. The following table shows the locations of these resources.

Resource | Description | URL
Macromedia website | General information about Macromedia products and services | http://www.macromedia.com
Information on ColdFusion | Detailed product information on ColdFusion and related topics | http://www.macromedia.com/coldfusion
Macromedia ColdFusion Support Center | Professional support programs that Macromedia offers | http://www.macromedia.com/support/coldfusion
ColdFusion Online Forum | Access to experienced ColdFusion developers through participation in the Online Forums, where you can post messages and read replies on many subjects relating to ColdFusion | http://webforums.macromedia.com/coldfusion/
Installation Support | Support for installation-related issues for all Macromedia products | http://www.macromedia.com/support/coldfusion/installation.html
Training | Information about classes, on-site training, and online courses offered by Macromedia | http://www.macromedia.com/support/training
Developer Resources | All the resources that you need to stay on the cutting edge of ColdFusion development, including online discussion groups, Knowledge Base, technical papers, and more | http://www.macromedia.com/desdev/developer/
Reference Desk | Development tips, articles, documentation, and white papers | http://www.macromedia.com/v1/developer/TechnologyReference/index.cfm
Macromedia Alliance | Connection with the growing network of solution providers, application developers, resellers, and hosting services creating solutions with ColdFusion | http://www.macromedia.com/partners/


About ColdFusion documentation

ColdFusion documentation is designed to provide support for the complete spectrum of participants. The print and online versions are organized to allow you to quickly locate the information that you need. The ColdFusion online documentation is provided in HTML and Adobe Acrobat formats.


Viewing online documentation

All ColdFusion documentation is available online in HTML and Adobe Acrobat PDF formats. To view the HTML documentation, open the following URL on the web server running ColdFusion: http://web_root/cfdocs/dochome.htm.

ColdFusion documentation in Acrobat format is available on the ColdFusion product CD-ROM.


Introduction to ColdFusion MX

This chapter describes ColdFusion MX and the role it plays in Internet applications, including Flash MX based applications. It also provides an introduction to the topics discussed in this book.

Contents
  • About Internet applications and Web application servers
  • About ColdFusion MX
  • Using ColdFusion MX with Macromedia Flash MX
  • About J2EE and the ColdFusion architecture
  • ColdFusion features described in this book
Next


About Internet applications and Web application servers

With ColdFusion MX, you develop Internet applications that run on web application servers. The following sections introduce Internet applications and web application servers. Later sections explain the specific role that ColdFusion MX plays in this environment.


About web pages and Internet applications

The Internet has evolved from a collection of static HTML pages to an application deployment platform. First, the Internet changed from consisting of static web pages to providing dynamic, interactive content. Rather than providing unchanging content where organizations merely advertise goods and services, dynamic pages enable companies to conduct business ranging from e-commerce to managing internal business processes. For example, a static HTML page lets a bookstore publish its location, list services such as the ability to place special orders, and advertise upcoming events like book signings. A dynamic website for the same bookstore lets customers order books online, write reviews of books they read, and even get suggestions for purchasing books based on their reading preferences.

More recently, the Internet has become the underlying infrastructure for a wide variety of applications. With the arrival of technologies such as XML, web services, J2EE (Java 2 Platform, Enterprise Edition), and Microsoft .NET, the Internet has become a multifaceted tool for integrating business activities. Now, enterprises can use the Internet to integrate distributed activities, such as customer service, order entry, order fulfillment, and billing.

ColdFusion MX is a rapid application development environment that lets you build dynamic websites and Internet applications quickly and easily. It lets you develop sophisticated websites and Internet applications without knowing the details of many complex technologies, yet it lets advanced developers take advantage of the full capabilities of many of the latest Internet technologies.


About web application servers

To understand ColdFusion, you must first understand the role of web application servers. Typically, web browsers make requests, and web servers, such as Microsoft IIS and the Apache web server, fulfill those requests by returning the requested information to the browser. This information includes, but is not limited to, HTML and Macromedia Flash files.

However, a web server’s capabilities is limited because all it does is wait for requests to arrive and attempt to fulfill those requests as soon as possible. A web server does not let you do the following tasks:

  • Interact with a database, other resource, or other application.
  • Serve customized information based on user preferences or requests.
  • Validate user input.

A Web server, basically, locates information and returns it to a web browser.

To extend the capabilities of a web server, you use a web application server, a software program that extends the web server’s capabilities to do tasks such as those in the preceding list.


How a web server and web application server work together

The following steps explain how a web server and web application server work together to process a page request.

  1. The user requests a page by typing a URL in a browser, and the web server receives the request.
  2. The web server looks at the file extension to determine whether a web application server must process the page. Then, one of the following actions occur:
  3. If the user requests a file that is a simple web page (often one with an HTM or HTML extension), the web server fulfills the request and sends the file to the browser.
  4. If the user requests a file that is a page that a web application server must process (one with a CFM, CFML, or CFC extension for ColdFusion requests), the web server passes the request to the web application server. The web application server processes the page and sends the results to the web server, which returns those results to the browser. The following figure shows this process:

This is a picture of the feature being described.

Because web application servers interpret programming instructions and generate output that a web browser can interpret, they let web developers build highly interactive and data-rich websites, that can do tasks such as the following:

  • Query other database applications for data.
  • Dynamically populate form elements.
  • Dynamically generate Flash application data.
  • Provide application security
  • Integrate with other systems using standard protocols such as HTTP, FTP, LDAP, POP, and SMTP
  • Create shopping carts and e-commerce websites.
  • Respond with an e-mail message immediately after a user submits a form.
  • Return the results of keyword searches.


About ColdFusion MX

ColdFusion MX is a rapid server scripting environment server for creating rich Internet applications. ColdFusion MX CFML, an easy-to-learn tag-based scripting language, with connectivity to enterprise data and powerful built-in search and charting capabilities. ColdFusion MX enables developers to easily build and deploy dynamic web sites, content publishing systems, self-service applications, commerce sites, and more.

ColdFusion MX consists of the following core components:

  • ColdFusion scripting environment
  • ColdFusion Application Services
  • The ColdFusion Administrator

The following sections describe these core components in more detail.


The ColdFusion scripting environment

The ColdFusion scripting environment provides an efficient development model for Internet applications. At the heart of the ColdFusion scripting environment is the ColdFusion Markup Language (CFML), a tag-based programming language that encapsulates many of the low level details of web programming in high-level tags and functions.


ColdFusion Markup Language

ColdFusion Markup Language (CFML) is a tag-based language, similar to HTML, that uses special tags and functions. With CFML, you can enhance standard HTML files with database commands, conditional operators, high-level formatting functions, and other elements to rapidly produce easy-to-maintain web applications. However, CFML is not limited to enhancing HTML. For example, you can create Flash applications consisting entirely of Flash elements and CFML. Similarly, you can use CFML to create web services for use by other applications.

The following sections briefly describe basic CFML elements. For more information, see Elements of CFML.


CFML tags

CFML looks similar to HTML -- it includes starting and, in most cases, ending tags, and each tag is enclosed in angle brackets. All ending tags are preceded with a forward slash
(/) and all tag names are preceded with cf; for example:

<cftagname>
   tag body text and CFML
</cftagname>

CFML increases productivity by providing a layer of abstraction that hides many low-level details involved with Internet application programming. At the same time, CFML is extremely powerful and flexible. ColdFusion lets you easily build applications that integrate files, databases, legacy systems, mail servers, FTP servers, objects, and components.

CFML includes approximately 100 tags. ColdFusion tags serve many functions. They provide programming constructs, such as conditional processing and loop structures. They also provide services, such as charting and graphing, full-text search, access to protocols such as FTP, SMTP/POP, and HTTP, and much more. The following table lists a few examples of commonly-used ColdFusion tags:

Tag | Purpose
cfquery | Establishes a connection to a database (if one does not exist), executes a query, and returns results to the ColdFusion environment.
cfoutput | Displays output that can contain the results of processing ColdFusion functions, variables, and expressions.
cfset | Sets the value of a ColdFusion variable.
cfmail | Lets an application send SMTP mail messages using application variables, query results, or server files. (Another tag, cfpop, gets mail.)
cfchart | Converts application data or query results into graphs, such as bar charts or pie charts, in Flash, JPG, or PNG format.
cfobject | Invokes objects written in other programming languages, including COM components, Java objects such as Enterprise JavaBeans, or CORBA objects.

The CFML Reference describes the CFML tags in detail.


CFML functions and CFScript

CFML includes approximately 270 built-in functions. These functions perform a variety of roles, including string manipulation, data management, and system functions. CFML also includes a built-in scripting language, CFScript, that lets you write code in that is familiar to programmers and JavaScript writers.


CFML extensions

You can extend CFML further by creating custom tags or user-defined functions (UDFs), or by integrating COM, C++, and Java components (such as JSP tag libraries). You can also create ColdFusion components, which encapsulate related functions and properties and provide a consistent interface for accessing them.

All these features let you easily create reusable functionality that is customized to the types of applications or websites that you are building.


CFML development tools

Macromedia Dreamweaver MX helps you develop ColdFusion applications efficiently. It includes many features that simplify and enhance ColdFusion development, including tools for debugging CFML. Because CFML is written in an HTML-like text format, and you often use HTML in ColdFusion pages, you can also use an HTML editor or a text editor, such as Notepad, to write ColdFusion applications.


Server-side ActionScript

Another feature of the ColdFusion scripting environment is server-side ActionScript. ActionScript is the JavaScript-based language used to write application logic in Macromedia Flash. By bringing this language to the server, ColdFusion MX enables Flash developers to use their familiar scripting environment to connect to ColdFusion resources and deliver the results to client-side applications using the integrated Macromedia Flash Remoting service. Using server-side ActionScript Flash programmers can create ColdFusion services, such as SQL queries, for use by Flash clients.

For more information about using Server-Side ActionScript in ColdFusion MX, see Using Server-Side ActionScript in ColdFusion MX.


ColdFusion Application Services

The ColdFusion application services are a set of built-in services that extend the capabilities of the ColdFusion scripting environment. These services include the following:

  • Charting and graphing service Generates visual data representations including line, bar, pie, and other charts.
  • Full-text search service Searches documents and databases using the Verity search engine.
  • Flash Remoting service Provides a high performance protocol for exchanging data with Flash MX clients.


The ColdFusion Administrator

The ColdFusion Administrator configures and manages the ColdFusion application server. It is a secure web-based application that you can access using any web browser, from any computer with an Internet connection.

You can manage the following options with the ColdFusion Administrator:

  • ColdFusion data sources
  • Debugging and logging output
  • Server settings
  • Application security

For more information about the ColdFusion Administrator, see Administering ColdFusion MX.


Using ColdFusion MX with Macromedia Flash MX

Macromedia Flash MX is designed to overcome the many limitations of HTML and solve the problem of providing efficient, interactive, user interfaces for Internet applications. ColdFusion MX is designed to provide a fast efficient environment for developing and providing data-driven Internet applications on your server. Using the following features, ColdFusion MX and Flash MX can work together in a seamless manner to provide complete interactive Internet applications:

  • ColdFusion MX native Flash connectivity Lets Flash MX clients interact with ColdFusion MX in an efficient, secure, and reliable way. Flash MX includes ActionScript commands that connect to ColdFusion components (CFC) and ColdFusion pages. Flash clients communicate with ColdFusion applications using Action Message Format protocol over HTTP, which provides fast, lightweight, binary data transfer between the Flash client and ColdFusion.
  • Flash MX development application debugger Lets you trace your application logic as it executes between Flash and ColdFusion.
  • ColdFusion MX Server-Side ActionScript Lets Flash programmers familiar with ActionScript create ColdFusion services, such as SQL queries, for use by Flash clients.

Together, these features let developers build integrated applications that run on the Flash client and the ColdFusion scripting environment.

For more information about using Server-Side ActionScript in ColdFusion MX, see Using Server-Side ActionScript in ColdFusion MX. For more information on developing Flash applications in ColdFusion, see Using the Flash Remoting service. For more information about using Flash MX, go to the following URL: http://www.macromedia.com.


About J2EE and the ColdFusion architecture

As the Internet software market has matured, the infrastructure services required by distributed Internet applications, including ColdFusion applications, have become increasingly standardized. The most widely adopted standard today is the Java 2 Platform, Enterprise Edition (J2EE) specification. J2EE provides a common set of infrastructure services for accessing databases, protocols, and operating system functionality, across multiple operating systems.


About ColdFusion and the J2EE platform

ColdFusion MX uses the J2EE infrastructure for many of its base services. By implementing the ColdFusion scripting environment on top of the J2EE platform, ColdFusion MX takes advantage of the power of the J2EE platform, but provides this power through the easy-to-use ColdFusion scripting environment.

ColdFusion MX consists of a family of products that differ in how they integrate with and use J2EE services. (Some ColdFusion editions might not be available at the time of the first ColdFusion MX release.)

  • ColdFusion MX Server is a standalone servers that includes the entire infrastructure necessary to run ColdFusion applications, including an embedded Java server based on Macromedia JRun technology.
  • ColdFusion MX for J2EE Application Servers consists of editions of ColdFusion MX that enable you to add ColdFusion MX capabilities to a J2EE server installation, including Macromedia JRun and other J2EE application servers.

The following figure shows how these editions are structured. Each edition supports the same ColdFusion scripting environment and includes the built-in application services, while the different editions enable developers to deploy ColdFusion MX in the configuration of their choice.

This is a picture of the feature being described.


J2EE infrastructure services and J2EE application server

ColdFusion MX is implemented on the Java technology platform provided by a J2EE application server. It uses either an integrated J2EE infrastructure that uses Macromedia JRun technology, or an independent J2EE application server. The Java technology platform provides much of the core functionality required by ColdFusion, including database connectivity, naming and directory services, and other runtime services.

Because ColdFusion is built on a J2EE platform, you can easily integrate J2EE and Java functionality into your ColdFusion application. As a result, ColdFusion pages can do any of the following:

  • Use custom JSP (Java Server Pages) tags from JSP tag libraries
  • Interoperate with JSP pages
  • Use Java servlets
  • Use Java objects, including the J2EE Java API, JavaBeans, and Enterprise JavaBeans

For more information on using J2EE features in ColdFusion, see Integrating J2EE and Java Elements in CFML Applications.


ColdFusion features described in this book

ColdFusion provides a comprehensive set of features for developing and managing Internet applications. These features enhance the speed and ease of development, and let you dynamically deploy your applications, integrate new and legacy technologies, and build secure applications.

The following table describes the primary ColdFusion features that are discussed in this book, and lists the chapters that describe them. This table is only a summary of major CFML features; this book also includes information about other features. Also, this table does not include features in other books.

Feature | Description | Chapters
CFML language | CFML is a fully featured tag-oriented Internet application language. It includes a wide range of tags, functions, variables, and expressions. | 2–5
CFScript | CFScript is a server-side scripting language that provides a subset of ColdFusion functionality in script syntax. | 6
Regular expressions | ColdFusion provides several functions that use regular expressions for string manipulation. It also lets you use regular expressions in text input tags. | 7, 25
Reusable elements | ColdFusion lets you create several types of elements, such as user-defined functions and ColdFusion components, that you write once and can use many times. | 8-12
User-defined functions (UDFs) | You can use CFScript or the cffunction tag to create your own functions. These functions can incorporate all of the built-in ColdFusion tags and functions, plus other extensions. | 9
Custom CFML tags | You can create custom ColdFusion tags using CFML. These tags can have bodies and can call other custom tags. | 10
ColdFusion components | ColdFusion components encapsulate multiple functions and related data in a single logical unit. ColdFusion components can have many uses, and are particularly useful in creating web services and Flash interfaces for your application. | 11
ColdFusion extension (CFX) tags | You can create custom tags in Java or C++. These tags can use features that are only available when using programming languages. However, CFX tags cannot have tag bodies. | 12
ColdFusion application structure | ColdFusion supports many ways of building an application, and includes specific features, such as the Application.cfm page, built-in security features, and shared scopes, that help you optimize your application structure. | 13-17
Error handling mechanisms | ColdFusion provides several mechanisms for handling data, including custom error pages and exception-handling tags and functions, such as cftry and cfcatch. | 14
Shared and persistent variable scopes | Using shared and persistent scopes, you can make data available to a single user over one or many browser sessions, or to multiple users of an application or server. | 15
Code locking | You lock sections of code that access in-memory shared scopes or use external resources that are not safe for multiple simultaneous access. | 15
Application security | ColdFusion provides mechanisms, including the cflogin tag, for authenticating users and authorizing them to access specific sections of your application. You can also use resource security, which secures access to ColdFusion resources based on the ColdFusion page location. | 16
Application Globalization | ColdFusion supports global applications that use different character sets and locales, and provides tags and functions designed to support globalizing your applications. | 17
Debugging tools | Using debugging output, the cftrace tag, logging features, and the Code Analyzer, you can locate and fix coding errors. | 18
Database access and management | ColdFusion can access SQL databases to retrieve, add, and modify data. This feature is one of the core functions of many dynamic applications. | 19–21
Queries of Queries | You can use a subset of standard SQL within ColdFusion to manipulate any data that is represented as a record set, including database query results, LDAP directory information, and other data. | 22
LDAP directory access and management | ColdFusion applications can access and manipulate data in LDAP (Lightweight Directory Access Protocol) directory services. These directories are often used for security validation data and other directory-like information. | 23
Indexing and searching data | ColdFusion applications can provide full-text search capabilities for documents and data sources using the Verity search engine. | 24-25
Dynamic forms | With ColdFusion, you can use HTML and forms to control the data displayed by a dynamic web page. You can also use the cfform tag to enrich your forms with sophisticated graphical controls, and perform input data validation. | 26-27
Data graphing | You can use the cfchart tag to display your data graphically. | 28
Flash integration | You can use native Flash connectivity built into Macromedia ColdFusion MX to help build dynamic Flash user interfaces for ColdFusion applications. | 29
XML document processing and creation | ColdFusion applications can create, use, and manipulate XML documents. ColdFusion also provides tools to use Web Distributed Data Exchange (WDDX), an XML dialect for transmitting structured data. | 30
Web services | ColdFusion applications can use available SOAP-based web services, including Microsoft .NET services. ColdFusion applications can also use ColdFusion components to provide web services to other applications over the Internet. | 31
Java and J2EE Integration | You can integrate J2EE elements, including JSP pages, JSP tag libraries, and Java objects, including Enterprise JavaBeans (EJBs), into your ColdFusion application. | 32
COM and CORBA objects | The cfobject tag lets you use COM (Component Object Model) or DCOM (Distributed Component Object Model) and CORBA (Common Object Request Broker) objects in your ColdFusion applications. | 33
E-mail messages | You can add interactive e-mail features to your ColdFusion applications using the cfmail and cfpop tags. | 34
HTTP and FTP | The cfhttp and cfftp tags provide simple methods of using HTTP (Hypertext Transfer Protocol) and FTP (File Transfer Protocol) communications in your application. | 35
File and directory access | You can use the cffile, cfdirectory, and cfcontent tags to read, write, and manage files and directories on the server. | 36
Previous


Elements of CFML

This chapter provides an overview of the basic elements of CFML, including tags, functions, constants, variables, expressions, and CFScript.

Contents
  • Character Case
  • Tags
  • Functions
  • Expressions
  • Constants
  • Variables
  • Data Types
  • ColdFusion components
  • CFScript
  • Flow Control
  • Comments
  • Special Characters
  • Reserved Words
Next


Introduction

This chapter introduces and describes the basic elements of CFML. These elements make CFML a powerful tool for developing interactive web applications. Because CFML is a dynamic application development tool, it has many of the features of a programming language, including the following:

  • Functions
  • Expressions
  • Variables and constants
  • Flow-control constructs such as if-then and loops

CFML also has a "language within a language", CFScript, which enables you to use a syntax similar to JavaScript for many operations.

This chapter introduces these elements and other basic CFML entities such as data types, comments, escape characters, and reserved words.

The remainder of Part I of this guide provides more detailed information on many of the basic CFML elements. The rest of this guide helps you use these elements effectively in your applications.


Character Case

The ColdFusion Server is case-insensitive. For example, the following all represent the cfset tag: cfset, CFSET, CFSet, and even cfsEt. However, you should get in the habit of consistently using the same case rules in your programs. For example:

  • Develop consistent rules for case use, and stick to them. If you use lowercase characters for some tag names, use them for all tag names.
  • Always use the same case for a variable. For example, don’t use both myvariable and MyVariable to represent the same variable on a page.

If you follow these rules, you will prevent errors on application pages where you use both CFML and case-sensitive languages, such as JavaScript,


Tags

ColdFusion tags tell the ColdFusion Server that it must process information. The ColdFusion Server only processes tag contents; it returns text outside of ColdFusion to the Web server unchanged. ColdFusion provides a wide variety of built-in tags and lets you create custom tags.


Tag syntax

ColdFusion tags have the same format as HTML tags. They are enclosed in angle brackets (< and >) and can have zero or more named attributes. Many ColdFusion tags have bodies; that is, they have beginning and end tags with text to be processed between them. For example:

<cfoutput>
   Hello #YourName#! <br>
</cfoutput>

Other tags, such as cfset and cfftp,never have bodies; all the required information goes between the beginning (<) character and the ending (>) character, as in the following example:

<cfset YourName="Bob">

Sometimes, although the tag can have a body, you do not need to put anything in it because the attributes specify all the required information. You can omit the end tag and put a forward slash character before the closing (>) character, as in the following example:

<cfexecute name="C:\winNT\System32\netstat.exe" arguments = "-e"
outputfile="C:\Temp\out.txt" timeout = "1" />

Note: The cfset tag differs from other tags in that it has neither a body nor arguments. Instead, the tag encloses an assignment statement that assigns a value to a variable.


Built-in tags

Over 80 built-in tags make up the heart of ColdFusion. These tags have many uses, including the following:

  • Manipulating variables
  • Creating interactive forms
  • Accessing and manipulating databases
  • Displaying data
  • Controlling the flow of execution on the ColdFusion page
  • Handling errors
  • Processing CFML pages
  • Managing the CFML application framework
  • Manipulating files and directories
  • Using external tools and objects, including Verity collections, COM, Java, and CORBA objects, and executable programs
  • Using protocols, such as mail, http, ftp, and pop

Much of this document describes how to use these tags effectively. The CFML Reference documents each tag in detail.


Custom tags

ColdFusion lets you create custom tags. You can create two types of custom tags:

  • CFML custom tags that are ColdFusion pages
  • CFX tags that you write in a programing language such as Java or C++

Custom tags can encapsulate frequently used business logic or display code. These tags enable you to place frequently used code in one place and call it from many places. Custom tags also let you abstract complex logic into a single, simple interface. They provide an easy way to distribute your code to others; you can even distribute encrypted versions of the tags to prevent access to the tag logic.

Currently, over 1,000 custom tags are available on the Macromedia developer’s exchange (http://www.coldfusion.com/Developer/Gallery/index.cfm). They perform tasks ranging from checking if Cookies and JavaScript are enabled on the client's browser to moving items from one list box to another. Many of these tags are free and include source code.


CFML custom tags

When you write a custom tag in CFML, you can take advantage of all the features of the ColdFusion language, including all built-in tags and even other custom tags. CFML custom tags can include body sections and end tags. Because they are written in CFML, you do not need to know a programming language such as Java. CFML custom tags provide more capabilities than user-defined functions, but are less efficient.

For more information on CFML custom tags, see Creating and Using Custom CFML Tags. For information about, and comparisons among, ways to reuse ColdFusion code, including CFML custom tags, user-defined functions, and CFX tags, see Reusing Code in ColdFusion Pages


CFX Tags

CFX tags are ColdFusion custom tags that you write in a programming language such as Java or C++. These tags can take full advantage of all the tools and resources provided by these languages, including their access to runtime environments. CFX tags also generally execute faster than CFML custom tags because they are compiled. CFX tags can be cross-platform, but are often platform-specific, for example if they take advantage of COM objects or the Windows API.

For more information on CFX tags, see Building Custom CFXAPI Tags.


Functions

Functions typically manipulate data and return a result. CFML includes over 250 built-in functions. You can also use CFScript to create user-defined functions (UDFs), sometimes referred to as custom functions.

Functions have the following general form:

functionName([argument1[, argument2]]...)

Some functions, such as the Now function take no arguments. Other functions require one or more comma-separated arguments and can have additional optional arguments. All ColdFusion functions return a value. For example, Round(3.14159) returns the value 3.


Built-in functions

ColdFusion built-in functions perform a variety of tasks, including, but not limited to, the following:

  • Creating and manipulating complex data variables, such as arrays, lists, and structures
  • Creating and manipulating queries
  • Creating, analyzing, manipulating, and formatting strings and date and time values
  • Evaluating the values of dynamic data
  • Determining the type of a variable value
  • Converting data between formats
  • Performing mathematical operations
  • Getting system information and resources

For alphabetical and categorized lists of ColdFusion functions, see the CFML Reference.

You use built-in functions throughout ColdFusion pages. Built-in functions are frequently used in a cfset or cfoutput tag to prepare data for display or further use. For example, the following line displays today’s date in the format October 12, 2001:

<cfoutput>#DateFormat(Now(), "mmmm d, yyyy")#</cfoutput>

Note that this code uses two nested functions. The Now function returns a ColdFusion date-time value representing the current date and time. The DateFormat function takes the value returned by the Now function and converts it to the desired string representation.

Functions are also valuable in CFScript scripts. ColdFusion does not support ColdFusion tags in CFScript, so you must use functions to access ColdFusion functionality in scripts.


User-defined functions

You can write your own functions, user-defined functions (UDFs). You can use these functions in ColdFusion expressions or in CFScript. You can call a user-defined function anywhere you can use a built-in CFML function. You create UDFs using the cffunction tag or the CFScript function statement. UDFs that you create using the cffunction tag can include ColdFusion tags and functions. UDFs that you create in CFScript can only include functions.

User-defined functions allow you to encapsulate logic and operations that you use frequently in a single unit. This way, you can write the code once and use it multiple times. UDFs ensure consistency of coding and enable you to structure your CFML more efficiently.

Typical user-defined functions include mathematical routines, such as a function to calculate the logarithm of a number; string manipulation routines, such as a function to convert a numeric monetary value to a string such as "two dollars and three cents"; and can even include encryption and decryption routines.

Note: The Common Function Library Project at http://www.cflib.org includes a number of free libraries of user-defined functions.

For more information on user-defined functions, see Writing and Calling User-Defined Functions.


Expressions

ColdFusion expressions consist of operands and operators. Operands are comprised of constants and variables, such as "Hello" or MyVariable. Operators, such as the string concatenation operator (&) or the division operator (/) are the verbs that act on the operands. ColdFusion functions also act as operators.

The simplest expression consists of a single operand with no operators. Complex expressions consist of multiple operands and operators. For example, the following statements are all ColdFusion expressions:

12
MyVariable
(1 + 1)/2
"father" & "Mother"
Form.divisor/Form.dividend
Round(3.14159)

The following sections briefly describe constants and variables. For detailed information on using variables, see Using ColdFusion Variables. For detailed information on expressions and operators, see Using Expressions and Pound Signs.


Constants

The value of a constant does not change during program execution. Constants are simple scalar values that you can use within expressions and functions, such as "Robert Trent Jones" and 123.45. Constants can be integers, real numbers, time and date values, Boolean values, or text strings. ColdFusion does not allow you to give names to constants.


Variables

Variables are the most frequently used operands in ColdFusion expressions. Variable values can be set and reset, and can be passed as attributes to CFML tags. Variables can be passed as parameters to functions, and can replace most constants.

ColdFusion has a number of built-in variables that provide information about the server and are returned by ColdFusion tags. For a list of the ColdFusion built-in variables, see the CFML Reference.

The following two characteristics classify a variable:

  • The scope of the variable, which indicates where the information is available and how long the variable persists
  • The data type of the variable’s value, which indicates the kind of information a variable represents, such as number, string, or date

The following section lists and briefly describes the variable scopes. Data Types lists data types (which also apply to constant values). For detailed information on ColdFusion variables, including data types, scopes, and their use, see Using ColdFusion Variables.


Variable scopes

The following table briefly lists ColdFusion variable scopes:

Scope | Description
Variables (local) | The default scope for variables of any type that are created with the cfset and cfparam tags. A local variable is available only on the page on which it is created and any included pages.
Form | The variables passed from a form page to its action page as the result of submitting the form.
URL | The parameters passed to the current page in the URL that is used to call it.
Attributes | The values passed by a calling page to a custom tag in the custom tag’s attributes. Used only in custom tag pages.
Caller | A reference, available in a custom tag, to the Variables scope of the page that calls the tag. Used only in custom tag pages.
ThisTag | Variables that are specific to a custom tag, including built-in variables that provide information about the tag. Used only in custom tag pages. A nested custom tag can use the cfassociate tag to return values to the calling tag’s ThisTag scope.
Request | Variables that are available to all pages, including custom tags and nested custom tags, that are processed in response to an HTTP request. Used to hold data that must be available for the duration of one HTTP request.
CGI | Environment variables identifying the context in which a page was requested. The variables available depend on the browser and server software.
Cookie | Variables maintained in a user’s browser as cookies.
Client | Variables that are associated with one client. Client variables let you maintain state as a user moves from page to page in an application and are available across browser sessions.
Session | Variables that are associated with one client and persist only as long as the client maintains a session.
Application | Variables that are associated with one, named, application on a server. The cfapplication tag name attribute specifies the application name.
Server | Variables that are associated with the current ColdFusion Server. This scope lets you define variables that are available to all your ColdFusion pages, across multiple applications.
Flash | Variables sent by a Macromedia Flash movie to ColdFusion and returned by ColdFusion to the movie.
Arguments | Variables passed in a call to a user-defined function or ColdFusion component method.
This | Variables that are declared inside a ColdFusion component or in a cffunction tag that is not part of a ColdFusion component.
function local | Variables that are declared in a user-defined function and exist only while the function executes.


Data Types

ColdFusion is considered "typeless" because you do not explicitly specify variable data types. However, ColdFusion data, the constants and the data that variables represent, do have data types, which correspond to the ways the data is stored on the computer.

ColdFusion data belongs to the following type categories:

Category
Description and types
Simple
Represents one value. You can use simple data types directly in ColdFusion expressions. ColdFusion simple data types are:
  • strings, such as "This is a test."
  • integers, such as 356
  • real numbers, such as -3.14159
  • Boolean values, True or False
  • date-time values, such as 3:00 PM July 12, 2001
Complex
A container for data. Complex variables generally represent more than one value. ColdFusion built-in complex data types are:
  • arrays
  • structures
  • queries
Binary
Raw data, such as the contents of a GIF file or an executable program file
Object
COM, CORBA, Java, web services, and ColdFusion Component objects: Complex objects that you create and access using the cfobject tag and other specialized tags.

For more information on ColdFusion data types, see Using ColdFusion Variables.


ColdFusion components

ColdFusion components encapsulate multiple, related, functions. A ColdFusion component is essentially a set of related user-defined functions and variables, with additional functionality to provide and control access to the component contents. ColdFusion components can make their data private, so that it is available to all functions (also called methods) in the component, but not to any application that uses the component.

ColdFusion components have the following features:

  • They are designed to provide related services in a single unit.
  • They can provide web services and make them available over the internet.
  • They can providing ColdFusion services that Flash clients can call directly.
  • They have several features that are familiar to object-oriented programmers including data hiding, inheritance, packages, and introspection.

For more information on ColdFusion components, see Building and Using ColdFusion Components


CFScript

CFScript is a language within a language. CFScript is a scripting language that is similar to JavaScript but is simpler to use. Also, unlike JavaScript CFScript only runs on the ColdFusion Server; it does not run on the client system. A CFScript script can use all ColdFusion functions and all ColdFusion variables that are available in the script’s scope.

CFScript provides a compact and efficient way to write ColdFusion logic. Typical uses of CFScript include:

  • Simplifying and speeding variable setting
  • Building compact flow control structures
  • Encapsulating business logic in user-defined functions

The following sample script populates an array and locates the first array entry that starts with the word "key". It shows several of the elements of CFScript, including setting variables, loop structures, script code blocks, and function calls. Also note that the code uses a cfoutput tag to display its results. While you can use CFSCript for output, the cfoutput tag is usually easier to use.

<cfscript>
strings = ArrayNew(1);
strings[1]="the";
strings[2]="key to our";
strings[4]="idea";
for( i=1 ; i LE 4 ; i = i+1 )
{
   if(Find("key",strings[i],1))
      break; }
</cfscript>
<cfoutput>Entry #i# starts with "key"</cfoutput><br>

You use CFScript to create user-defined functions

For more information on CFScript, see Extending ColdFusion Pages with CFML Scripting. For more information on user-defined functions, see Writing and Calling User-Defined Functions.


Flow Control

ColdFusion provides several tags that allow you to control how a page gets executed. These tags generally correspond to programming language flow control statements, such as if, then, and else. The following tags provide ColdFusion flow control.

Tags | Purpose
cfif, cfelseif, cfelse | Select sections of code based on whether expressions are True or False.
cfswitch, cfcase, cfdefaultcase | Select among sections of code based on the value of an expression. Case processing is not limited to True and False conditions.
cfloop, cfbreak | Loop through code based on any of the following values: entries in a list, keys in a structure or external object, entries in a query column, an index, or the value of a conditional expression.
cfabort, cfexit | End processing of a ColdFusion page or custom tag.

This section provides a basic introduction to using flow-control tags. CFScript also provides a set of flow-control statements. For information on using flow-control statements in CFScript, see Extending ColdFusion Pages with CFML Scripting. For more details on using flow-control tags, see the reference pages for these tags in the CFML Reference


cfif, cfelseif, and cfelse

The cfif, cfelseif, and cfelse tags provide if-then-else conditional processing, as follows:

  1. The cfif tag tests a condition and executes its body if the condition is True.
  2. If the preceding cfif (or cfelseif) test condition is False, the cfelseif tag tests another condition and executes its body if that condition is True.
  3. The cfelse tag can optionally follow a cfif tag and zero or more cfelseif tags. Its body executes if all the preceding tags’ test conditions are False.

The following example shows the use of the cfif, cfelseif, and cfelse tags. If the value of the type variable is "Date" the date displays; if the value is "Time" the time; displays otherwise, both the time and date display.

<cfif type IS "Date">
   <cfoutput>#DateFormat(Now())#</cfoutput>
<cfelseif type IS "Time">
   <cfoutput>#TimeFormat(Now())#</cfoutput>
<cfelse>
   <cfoutput>#TimeFormat(Now())#, #DateFormat(Now())#</cfoutput>
</cfif>


cfswitch, cfcase, and cfdefaultcase

The cfswitch, cfcase, and cfdefaultcase tags let you to select among different code blocks based on the value of an expression. ColdFusion processes these tags as as follows:

  1. The cfswitch tag evaluates an expression. The cfswitch tag body contains one or more cfcase tags and optionally includes cfdefaultcase tag.
  2. Each cfcase tag in the cfswitch tag body specifies a value or set of values. If a value matches the value determined by the expression in the cfswitch tag, ColdFusion runs the code in the body of the cfcase tag and then exits the cfswitch tag. If two cfcase tags have the same condition, ColdFusion generates an error.
  3. If none of the cfcase tags match the value determined by the cfswitch tag, and the cfswitch tag body includes a cfdefaultcase tag, ColdFusion runs the code in the cfdefaultcase tag body.

Note: Although the cfdefaultcase tag does not have to follow all cfcase tags, it is good programming practice to put it at the end of the cfswitch statement.

The cfswitch tag provides better performance than a cfif tag with multiple cfelseif tags, and is easier to read. Switch processing is commonly used when different actions are required based on a a string variable such as a month or request identifier.

The following example shows switch processing:

<cfoutput query = "GetEmployees">
<cfswitch expression = #Department#>
   <cfcase value = "Sales">
      #FirstName# #LastName# is in <b>Sales</b><br><br>
   </cfcase>
   <cfcase value = "Accounting">
      #FirstName# #LastName# is in <b>Accounting</b><br><br>
   </cfcase>
   <cfcase value = "Administration">
      #FirstName# #LastName# is in <b>Administration</b><br><br>
   </cfcase>
   <cfdefaultcase>#FirstName# #LastName# is not in Sales,
      Accounting, or Administration.<br>
   </cfdefaultcase>
</cfswitch>
</cfoutput>


cfloop and cfbreak

The cfloop tag loops through the tag body zero or more times based on a condition specified by the tag attributes. The cfbreak tag exits a cfloop tag.


cfloop

The cfloop tag provides five types of loops:

Loop type | Description
Index | Loops through the body of the tag and increments a counter variable by a specified amount after each loop until the counter reaches a specified value.
Conditional | Checks a condition and runs the body of the tag if the condition is Tru.e
Query | Loops through the body of the tag once for each row in a query.
List | Loops through the body of the tag once for each entry in a list.
Collection | Loops through the body of the tag once for each key in a ColdFusion structure or item in a COM/DCOM object.

The following example shows a simple index loop:

<cfloop index = "LoopCount" from = 1 to = 5>
The loop index is <cfoutput>#LoopCount#</cfoutput>.<br>
</cfloop>

The following example shows a simple conditional loop. The code does the following:

  1. Sets up a ten-element array with the word "kumquats" in the fourth entry.
  2. Loops through the array until it encounters an array element containing "kumquats" or it reaches the end of the array.
  3. Prints out the value of the Boolean variable that indicates whether it found the word "kumquats" and the array index at which it exited the loop.
<cfset myArray = ArrayNew(1)>
<!--- Use ArraySet to initialize the first ten elements to 123 --->
<cfset ArraySet(myArray, 1, 10, 123)>
<cfset myArray[4] = "kumquats">

<cfset foundit = False>
<cfset i = 0>
<cfloop condition = "(NOT foundit) AND (i LT ArrayLen(myArray))">
   <cfset i = i + 1>
   <cfif myArray[i] IS "kumquats">
      <cfset foundit = True>
   </cfif>
</cfloop>
<cfoutput>
i is #i#<br>
foundit is #foundit#<br>
</cfoutput>

Note: You can get an infinite conditional loop if you do not force an end condition. In this example, the loop is infinite if you omit the <cfset i = i + 1> statement. To end an infinite loop, stop the ColdFusion application server.


cfbreak

The cfbreak tag exits the cfloop tag. You typically use it in a cfif tag to exit the loop if a particular condition occurs. The following example shows the use of a cfbreak tag in a query loop:

<cfloop query="fruitOrder">
   <cfif fruit IS "kumquat">
      <cfoutput>You cannot order kumquats!<br></cfoutput>
      <cfbreak>
   </cfif>
   <cfoutput>You have ordered #quantity# #fruit#.<br></cfoutput>
</cfloop>


cfabort and cfexit

The cfabort tag stops processing of the current page at the location of the cfabort tag. ColdFusion returns to the user or calling tag everything that was processed before the cfabort tag. You can optionally specify an error message to display. You can use the cfabort tag as the body of a cfif tag to stop processing a page when a condition, typically an error, occurs.

The cfexit tag controls the processing of a custom tag, and can only be used in ColdFusion custom tags. For more information see, Terminating tag execution and the CFML Reference.


Comments

ColdFusion comments have a similar format to HTML comments. However, they use three dash characters instead of two; for example:

<!--- This is a ColdFusion Comment. Browsers do not receive it. --->

The ColdFusion Server removes all ColdFusion comments from the page before returning it to the Web server. As a result, the page that a user browser receives does not include the comment, and users cannot see it even if they view the page source.

You can embed CFML comments in begin tags (not just tag bodies), functions calls, and variable text in pound signs. ColdFusion ignores the text in comments such as the following:

<cfset MyVar = var1 <!--- & var2 --->>
<cfoutput>#Dateformat(now() <!---, "dddd, mmmm yyyy" --->)#</cfoutput>

This technique can be useful if you want to temporarily comment out parts of expressions or optional attributes or arguments.

Note: You cannot embed comments inside a tag names or function name, such as <cf_My<!--- New --->CustomTag>. You also cannot embed comments inside strings, as in the following example: IsDefined("My<!--- New --->Variable").


Special Characters

The double quote ("), single quote ('), and pound sign (#) characters have special meaning to ColdFusion. To include any of them in a string, double the character; for example, use ## to represent a single # character.

The need to escape the single- and double-quotes is context-sensitive. Inside a double-quoted string, you do not need to escape single-quote (apostrophe) characters. Inside a single-quoted string, you do not escape double-quote characters.

The following example illustrates escaping special characters, including the use of mixed single and double quotes.

<cfset mystring = "We all said ""For He's a jolly good fellow.""">
<cfset mystring2 = 'Then we said "For She''s a jolly good fellow".'>
<cfoutput>
   #mystring#<br>
   #mystring2#<br>
   Here is a pound sign: ##
</cfoutput>

The output looks like this:

We all said "For He's a jolly good fellow."
Then we said "For She's a jolly good fellow."
Here is a pound sign: #


Reserved Words

As with any programming tool, you cannot use just any word or name for ColdFusion variables, UDFs and custom tags. You must avoid using any name that can be confused with a ColdFusion element. In some cases, if you use a word that ColdFusion uses, for example, a built-in structure name. you can overwrite the ColdFusion data.

The following list indicates words you must not use for ColdFusion variables, user-defined function names, or custom tag names. While some of these words can be used safely in some situations, you can prevent errors by avoiding them entirely. For a complete list of reserved words, see the CFML Reference.

  • Built-in function names, such as Now or Hash
  • Scope names, such as Form or Session
  • Any name starting with cf. However, when you call a CFML custom tag directly, you prefix the custom tag page name with cf_.
  • Operators, such as NE or IS
  • The names of any built-in data structures, such as Error or File
  • The names of any built-in variables, such as RecordCount or CGI variable names
  • CFScript language element names such as for, default, or continue

You must also not create form field names ending in any of the following, except to specify a form field validation rule using a hidden form field name. (For more information on form field validation, see Validating form field data types.)

  • _integer
  • _float
  • _range
  • _date
  • _time
  • _eurodate

Remember that ColdFusion is not case-sensitive. For example, all of the following are reserved words: IS, Is, iS, and is.

Previous


Using ColdFusion Variables

This chapter provides detailed information on ColdFusion variables and their use. ColdFusion variables are the most frequently used operands in ColdFusion expressions. Variable values can be set and reset, and can be passed as attributes to CFML tags. Variables can be passed as parameters to functions, and can replace most constants.

This chapter describes how to create and use variables. It provides information on how variables can represent different types of data and how the data types get converted. It also discusses how variables exists in different scopes and provides an introduction to how the scopes are used. Finally, it provides additional information required to use variables correctly.

Contents
  • Creating Variables
  • Variable Characteristics
  • Data Types
  • Using periods in variable references
  • Data Type Conversion
  • About scopes
  • Ensuring Variable Existence
  • Validating Data Types Validating Data Types
  • Passing Variables to Custom Tags and UDFs
Next


Creating Variables

You create most ColdFusion variables by assigning them values. (You must use the ArrayNew function to create arrays.) Most commonly, you create variables by using the cfset tag. You can also use the cfparam tag, and assignment statements in CFScript. Tags that create data objects also create variables. For example, the cfquery tag creates a query object variable.

ColdFusion automatically creates some variables that provide information about the results of certain tags or operations. ColdFusion also automatically generates variables in certain scopes, such as Client and Server. For information on these special variables, see the CFML Reference and the documentation of the CFML tags that create these variables.

ColdFusion generates an error when it tries to use a variable before it is created. This can happen, for example, when processing data from an incompletely filled form. To prevent such errors, test for the variable's existence before you use it. For more information on testing for variable existence, see Ensuring Variable Existence.

For more information on how to create variables, see Creating and using variables in scopes.


Variable naming rules

Variable names must conform to Java naming rules. When naming ColdFusion variables and form fields, follow these guidelines:

  • A variable name must begin with a letter, underscore, or Unicode currency symbol.
  • The initial character can by followed by any number of letters, numbers, and underscore characters. Unicode currency symbols are also allowed.
  • A variable name cannot contain spaces.
  • A query result is a type of variable, so it cannot have the same name as another local variable in the current ColdFusion application page.
  • ColdFusion variables are not case-sensitive. However, consistent capitalization makes the code easier to read.
  • When creating a form with fields that are used in a query, match form field names with the corresponding database field names.
  • Prefix each variable’s name with its scope. Although some ColdFusion programmers do not use the Variables prefix for local variable names, you should use prefixes for all other scopes. Using scope prefixes makes variable names clearer and increases code efficiency. In some cases, you must prefix the scope. For more information, see About scopes.
  • Periods separate the components of structure or object names. They also separate a variable scope from the variable name. You cannot use periods in simple variable names, with the exception of variables in the Cookie and Client scopes. For more information on using periods, see Using periods in variable references

Note: In some cases, when you use an existing variable name, you must put pound signs (#) around the name to allow ColdFusion to distinguish it from string or HTML text, and to insert its value, as opposed to its name. For more information, see Using Pound Signs.


Variable Characteristics

You can classify a variable using the following characteristics:

  • The data type of the variable value, which indicates the kind of information a variable represents, such as number, string, or date
  • The scope of the variable, which indicates where the information is available and how long the variable persists

The following sections provide detailed information on Data types and scopes.


Data Types

ColdFusion is often referred to as “typeless” because you do not assign types to variables and ColdFusion does not associate a type with the variable name. However, the data that a variable represents does have a type, and the data type affects how ColdFusion evaluates an expression or function argument. ColdFusion can automatically convert many data types into others when it evaluates expressions. For simple data, such as numbers and strings, the data type is unimportant until the variable is used in an expression or as a function argument.

ColdFusion variable data belongs to one of the following type categories:

  • Simple One value. ColdFusion simple data types include numbers, strings, Booleans, and date-time variables. You can use simple data types directly in ColdFusion expressions.
  • Complex A container for data. Complex variables generally represent more than one value. ColdFusion built-in complex data types include arrays, structures, queries, and XML document objects.

    • You cannot use a complex variable, such as an array, directly in a ColdFusion expression, but you can use simple data type elements of a complex variable in an expression.

    For example, with a one-dimensional array of numbers called myArray, you cannot use the expression myArray * 5. However, you could use an expression myArray[3] * 5 to multiply the third element in the array by five.

  • Binary Raw data, such as the contents of a GIF file or an executable program file.
  • Objects Complex constructs. Often, objects encapsulate both data and functional operations. The following table lists the types of objects that ColdFusion can use, and identifies the chapters that describe how to use them:

    Object type
    See
    Component Object Model (COM)
    Integrating COM and CORBA Objects in CFML Applications
    Common Object Request Broker Architecture (CORBA)
    Integrating COM and CORBA Objects in CFML Applications
    Java
    Integrating J2EE and Java Elements in CFML Applications
    ColdFusion component
    Building and Using ColdFusion Components
    Web service
    Using Web Services


Data type notes

Although ColdFusion variables do not have types, it is often convenient to refer to a variable’s type as a shorthand for the type of data that the variable represents.

ColdFusion can validate the type of data contained in form fields and query parameters. Form more information on form field data type validation, see Validating form field data types. For more information on query parameter validation, see Using cfqueryparam.

The cfdump tag displays the entire contents of a variable, including ColdFusion complex data structures. It is an excellent tool for debugging complex data and the code that handles it.

ColdFusion provides the following functions for identifying the data type of a variable:

  • IsArray
  • IsBinary
  • IsBoolean
  • IsObject
  • IsQuery
  • IsSimpleValue
  • IsStruct
  • IsXMLDoc

ColdFusion also includes the following functions for determining whether a string can be represented as another simple data type:

  • IsDate
  • IsNumeric

ColdFusion does not use a null data type. However, if ColdFusion receives a null value from an external source such as a database, a Java object, or some other mechanism, it maintains the null until you use it as a simple value. At that time, ColdFusion converts the null to an empty string ("").


Numbers

ColdFusion supports integers and real numbers. You can intermix integers and real numbers in expressions; for example, 1.2 + 3 evaluates to 4.2.


Integers

ColdFusion supports integers between -2,147,483,648 and 2,147,483,647 (32-bit signed integers). You can assign a value outside this range to a variable, but ColdFusion initially stores the number as a string. If you use it in an arithmetic expression, ColdFusion converts it into a floating point value, preserving its value, but losing precision. The following example shows this:

<cfset mybignum=12345678901234567890>
<cfset mybignumtimes10=(mybignum * 10)>
<cfoutput>mybignum is: #mybignum#</cfoutput><br>
<cfoutput>mybignumtimes10 is: #mybignumtimes10# </cfoutput><br>

This code generates the following output:

mybignum is: 12345678901234567890
mybignumtimes10 is: 1.23456789012E+020


Real numbers

Real numbers, numbers with a decimal part, are also known as floating point numbers. ColdFusion real numbers can range from approximately -10300 to approximately 10300. A real number can have up to 12 significant digits. As with integers, you can assign a variable a value with more digits, but the data is stored as a string. The string is converted to a real number, and can lose precision, when you use it in an arithmetic expression.

You can represent real numbers in scientific notation. This format is xEy, where x is a positive or negative real number in the range 1.0 (inclusive) to 10 (exclusive), and y is an integer. The value of a number in scientific notation is x times 10y. For example, 4.0E2 is 4.0 times 102, which equals 400. Similarly, 2.5E-2 is 2.5 times 10-2, which equals 0.025. Scientific notation is useful for writing very large and very small numbers.


Strings

In ColdFusion, text values are stored in strings. You specify strings by enclosing them in either single or double quotes. For example, the two strings below are equivalent:

"This is a string"
'This is a string'

You can write an empty string in the following ways:

  • "" (a pair of double quotes with nothing in between)
  • '' (a pair of single quotes with nothing in between)

Strings can be any length, limited by the amount of available memory on the ColdFusion Server. There is, however, a 64K limit on the size of text data that can be read from and written to a ColdFusion database or HTML text area. The ColdFusion Administrator lets you increase the limit for database string transfers, but doing so can reduce server performance. To change the limit, select the Enable retrieval of long text option on the Advanced Settings page for the data source.


Escaping quotes and pound signs

To include a single-quote character in a string that is single-quoted, use two single quotes (known as escaping the single quote). The following example uses escaped single quotes:

<cfset myString='This is a single quote: '' This is a double quote: "'>
<cfoutput>#mystring#</cfoutput><br>

To include a double-quote character in a double-quoted string, use two double quotes (known as escaping the double quote). The following example uses escaped double quotes:

<cfset myString="This is a single quote: ' This is a double quote: """>
<cfoutput>#mystring#</cfoutput><br>

Because strings can be in either double quotes or single quotes, both of the preceding examples display the same text:

This is a single quote: ' This is a double quote: "

Note: To insert a pound sign in a string, you must escape the pound sign, as in:
"This is a pound sign ##"


Lists

ColdFusion includes functions that operate on lists, but it does not have a list data type. In ColdFusion, a list is just a string that consists of multiple entries separated by delimiter characters.

The default delimiter for lists is the comma. If you use any other character to separate list elements, you must specify the delimiter in the list function. You can also specify multiple delimiter characters. For example, you can tell ColdFusion to interpret a comma or a semicolon as a delimiter, as the following example shows:

<cfset MyList="1,2;3,4;5">
<cfoutput>
List length using ; and , as delimiters: #listlen(Mylist, ";,")#<br>
List length using only , as a delimiter: #listlen(Mylist)#<br>
</cfoutput>

This example displays the following output:

List length using ; and , as delimiters: 5
List length using only , as a delimiter: 3

Each delimiter must be a single character. For example, you cannot tell ColdFusion to require two hyphens in a row as a delimiter.

If a list has two delimiters in a row, ColdFusion ignores the empty element. For example, if MyList is "1,2,,3,,4,,,5" and the delimiter is the comma, the list has five elements and list functions treat it the same as "1,2,3,4,5".


Booleans

A Boolean value represents whether something is true or false. ColdFusion has two special constants--True and False-- to represent these values. For example, the Boolean expression 1 IS 1 evaluates to True. The expression "Monkey" CONTAINS "Money" evaluates to False.

You can use Boolean constants directly in expressions, as in the following example:

<cfset UserHasBeenHere = True>

In Boolean expressions, True, non-zero numbers, and the string "Yes" are equivalent, and False, 0, and the string "No" are equivalent.

Boolean evaluation is not case-sensitive. For example, True, TRUE, and true are equivalent.


Date-Time Values

ColdFusion can perform operations on date and time values. Date-time values identify a date and time in the range 100 AD to 9999 AD. Although you can specify just a date or a time, ColdFusion uses one data type representation, called a date-time object, for date, time, and date and time values.

ColdFusion provides many functions to create and manipulate date-time values and to return all or part of the value in several different formats.

You can enter date and time values directly in a cfset tag with a constant as follows:

<cfset myDate = "October 30, 2001">

When you do this, ColdFusion stores the information as a string. If you use a date-time function, ColdFusion stores the value as a date-time object, which is a separate simple data type. When possible, use date-time functions such as CreateDate and CreateTime to specify dates and times, because these functions can prevent you from specifying the date or time in an invalid format and they create a date-time object immediately.


Date and time formats

You can directly enter a date, time, or date and time, using standard U.S. date formats. ColdFusion processes the two-digit-year values 0 to 29 as twenty-first century dates; it processes the two-digit-year values 30 to 99 as twentieth century dates. Time values are accurate to the second. The following table lists valid date and time formats:

To specify | Use these formats
Date | October 30, 2001 Oct 30, 2001 Oct. 30, 2001 10/30/01 2001-10-30 10-30-2001
Time | 02:34:12 2:34a 2:34am 02:34am 2am
Date and Time | Any combination of valid date and time formats, such as these: October 30, 2001 02:34:12 Oct 30, 2001 2:34a Oct. 30, 2001 2:34am 10/30/1 02:34am 2001-10-30 2am 10-30-2001 2am


Locale-specific dates and times

ColdFusion provides several functions that let you input and output dates and times (and numbers and currency values) in formats that are specific to the current locale. A locale identifies a language and locality, such as English (US) or French (Swiss). Use these functions to input or output dates and times in formats other than the U.S. standard formats. (Use the SetLocale function to specify the locale.) The following example shows how to do this:

<cfset oldlocale = SetLocale("French (Standard)")>
<cfoutput>#LSDateFormat(Now(), "ddd, mmmm dd, yyyy")#</CFOUTPUT>

This code outputs a line like the following:

ven., juin 15, 2001

For more information on international functions, see the CFML Reference.


How ColdFusion stores dates and times

ColdFusion stores and manipulates dates and times as date-time objects. Date-time objects store data on a time line as real numbers. This storage method increases processing efficiency and directly mimics the method used by many popular database systems. In date-time objects, one day is equal to the difference between two successive integers. The time portion of the date-and-time value is stored in the fractional part of the real number. The value 0 represents 12:00 AM 12/30/1899.

Although you can use arithmetic operations to manipulate date-and-time values directly, this method can result in code that is difficult to understand and maintain. Use the ColdFusion date-time manipulation functions instead.


Binary Data Type and Base64 Encoding

Binary data is raw data, such as the contents of a GIF file or an executable program file. You do not normally use binary data directly, but you can use the cffile tag to read a binary file into a variable, typically for conversion to Base64 encoding before transmitting the file by e-mail.

Base64 format encodes the data in the lowest six bits of each byte. It ensures that binary data and non-ANSI character data can be transmitted by e-mail without corruption. The MIME specification defines the Base64 encoding method.

ColdFusion does not have a Base64 data type; it processes Base64 encoded data as string data.

ColdFusion provides the following functions that convert among string data, binary data, and Base64 encoded string data:

Function | Description
ToBase64 | Converts string and binary data to Base64 encoded data.
ToBinary | Converts Base64 encoded data to binary data.
ToString | Converts most simple data types to string data. It can convert numbers, date-time objects, and boolean values. (It converts date-time objects to ODBC timestamp strings.) It cannot convert binary data that includes bytes that are not printable characters.

The ToString function cannot convert Base64 encoded data directly to an unencoded string. Use the following procedure to convert Base64 encoded data that was originally a string back to a readable string:

  1. Use the ToBinary function to convert the Base64 data into binary format.
  2. Use the ToString function to convert the binary data to string.

For example, the following two lines print the same results:

<cfoutput>This is a test</cfoutput>
<cfoutput>#ToString(ToBinary(ToBase64("This is a test")))#</cfoutput>

Do not use binary data or Base64 data directly in ColdFusion expressions.


Complex Data Types

Arrays, structures, and queries are ColdFusion built-in complex data types. Structures and queries are sometimes referred to as objects, because they are containers for data, not individual data values.

For details on using arrays and structures, see Using Arrays and Structures.


Arrays

Arrays are a way of storing multiple values in a table-like format that can have one or more dimensions. To create an array and specify its initial dimensions, use the ColdFusion ArrayNew function. For example, the following line creates an empty two-dimensional array:

<cfset myarray=ArrayNew(2)>

You reference elements using numeric indexes, with one index for each dimension. For example, the following code sets one element of a two-dimensional array to the current date and time.

<cfset myarray[1][2]=Now()>

The ArrayNew function can create arrays with up to three dimensions. However, there is no limit on array size or maximum dimension. To create arrays with more than three dimensions, create arrays of arrays.

After you create an array, you can use functions or direct references to manipulate its contents.

When you assign an existing array to a new variable, ColdFusion creates a new array and copies the old array’s contents to the new array. The following example creates a copy of the original array:

<cfset newArray=myArray>

For more information on using Arrays, see, Using Arrays and Structures.


Structures

ColdFusion structures consist of key-value pairs, where the keys are text strings and the values can be any ColdFusion data type, including other structures. Structures let you build a collection of related variables that are grouped under a single name. To create a structure, use the ColdFusion StructNew function. For example, the following line creates a new, empty, structure called depts:

<cfset depts=StructNew()>

You can also create a structure by assigning a value in the structure. For example, the following line creates a new structure called MyStruct with a key MyValue equal to 2.

<cfset MyStruct.MyValue=2>

Note: In previous ColdFusion versions, this line created a Variables scope variable named "MyStruct.MyValue" with the value 2.

After you create a structure, you can use functions or direct references to manipulate its contents, including adding key/value pairs.

You can use either of the following methods to reference elements stored in a structure:

  • StructureName.KeyName
  • StructureName["KeyName"]

The following examples show these methods:

depts.John="Sales"
depts["John"]="Sales"

When you assign an existing structure to a new variable, ColdFusion does not create a new structure. Instead, the new variable accesses the same data (location) in memory as the original structure variable. In other words, both variables are references to the same object.

For example, the following code creates a new variable myStructure2 that references the same structure as the myStructure variable:

<CFSET myStructure2=myStructure>

When you change the contents of myStructure2, you also change the contents of myStructure. To copy the contents of a structure, use the ColdFusion Duplicate function, which copies the contents of structures and other complex data types.

Structure key names can be the names of complex data objects, including structures or arrays. This lets you create arbitrarily complex structures.

For more information on using Structures, see Using Arrays and Structures.


Queries

A query object, sometimes referred to as a query, query result, or record set, is a complex ColdFusion data type that represents data in a set of named columns, similar to the columns of a database table. The following ColdFusion tags can create query objects:

  • cfquery
  • cfdirectory
  • cfhttp
  • cfldap
  • cfpop
  • cfprocresult

In these tags, the name attribute specifies the query object’s variable name. The QueryNew function also creates queries.

When you assign a query to a new variable, ColdFusion does not copy the query object. Instead, both names point to the same record set data. For example, the following code creates a new variable myQuery2 that references the same record set as the myQuery variable.

<CFSET myQuery2 = myQuery>

If you make changes to data in myQuery, myQuery2 also shows those changes.

You reference query columns by specifying the query name, a period, and the column name; for example:

myQuery.Dept_ID

When you reference query columns inside tags, such as cfoutput and cfloop, in which you specify the query name in a tag attribute, you do not have to specify the query name.

You can access query columns as if they are one-dimensional arrays. For example, the following code assigns the contents of the second row of the Employee column in the myQuery query to the variable myVar:

<CFSET myVar = myQuery.Employee[2]>

You cannot use array notation to refer to a row (of all columns) of a query.


Working with structures and queries

Because structure variables and query variables are references to objects, the rules in the following sections apply to both types of data.


Multiple references to an object

When multiple variables refer to a structure or query object, the object continues to exist as long as at least one reference to the object exists. The following example shows how this works:

<cfscript> depts = structnew();</cfscript>
<cfset newStructure=depts>
<cfset depts.John="Sales">
<cfset depts=0>
<cfoutput>
   #newStructure.John#<br>
   #depts#
</cfoutput>

This example displays the following output:

Sales
0

After the <cfset depts=0> tag executes, the depts variable does not refer to a structure; it is a simple variable with the value 0. However, the variable newStructure still refers to the original structure object.


Assigning objects to scopes

You can give a query or structure a different scope by assigning it to a new variable in the other scope. For example, the following line creates a Server variable, Server.SScopeQuery, using the local myquery variable:

<CFSET Server.SScopeQuery = myquery>

To clear the server scope query variable, reassign the query object, as follows:

<CFSET Server.SScopeQuery = 0>

This deletes the reference to the object from the server scope, but does not remove any other references that might exist.


Copying and duplicating objects

You can use the Duplicate function to make a true copy of a structure or query object. Changes to the copy do not affect the original.


Using a query column

When you are not inside a cfloop, cfoutput, or cfmail tag that has a query attribute, you can treat a query column as an array. However, query column references do not always behave as you might expect. This section explains the behavior of references to query columns using the results of the following cfquery tag in its examples:

<cfquery dataSource="CompanyInfo" name="myQuery">
   SELECT FirstName, LastName
   FROM Employee
</cfquery>

To reference elements in a query column, use the row number as an array index. For example, both of the following lines display the word "ben":

<cfoutput> #myQuery.Firstname[1]# </cfoutput><br>
<cfoutput> #myQuery["Firstname"][1]# </cfoutput><br>

ColdFusion behavior is less straightforward, however, when you use the query column references myQuery.Firstname and myQuery["Firstname"] without using an array index; as the two reference formats produce different results.

Here are the rules for these references:

If you refer to myQuery.Firstname, ColdFusion automatically converts it to the first row in the column. For example, the following line prints outs the word "ben":

<cfset myCol = myQuery.Firstname >
<cfoutput>#mycol#</cfoutput>

But the following lines display an error message.

<cfset myCol = myQuery.Firstname >
<cfoutput>#mycol[1]#</cfoutput><br>

If you refer to Query["Firstname"] ColdFusion does not automatically convert it to the first row of the column. For example, the following line results in an error message indicating that ColdFusion cannot convert a complex type to a simple value:

<cfoutput> #myQuery['Firstname']# </cfoutput><br>

Similarly, the following code prints out the name "marjorie", the value of the second row in the column

<cfset myCol = myQuery["Firstname"]>
<cfoutput>#mycol[2]#</cfoutput><br>

However, when you make an assignment that requires a simple value, ColdFusion automatically converts the query column to the value of the first row. For example, the following code displays the name "ben":

<cfoutput> #myQuery.Firstname# </cfoutput><br>
<cfset myVar= myQuery['Firstname']>
<cfoutput> #myVar# </cfoutput><br>

Got that? There will be a quiz Monday morning.


Using periods in variable references

ColdFusion uses the period (.) to separate elements of a complex variable such as a structure, query, XML document object, or external object, as in MyStruct.KeyName. A period also separates a variable scope identifier from the variable name, as in Variables.myVariable or CGI.HTTP_COOKIE.

With the exception of Cookie and Client scope variables (which must always be simple variable types), you cannot normally include periods in simple variable names. However, ColdFusion makes some exceptions that accommodate legacy and third-party code that does not conform to this requirement.

Note: For more information on scopes, see About scopes. For more information on references to arrays and structures, see Using Arrays and Structures. For more information on references to XML document objects, see Using XML and WDDX.


Understanding variables and periods

The following descriptions use a sample variable name MyVar.a.b to explain how ColdFusion uses periods when getting setting the variable value.


Getting a variable

ColdFusion can correctly get variable values even if a simple variable name includes a period. For example, the following set of steps shows how ColdFusion gets MyVar.a.b, as in <cfset Var2 = myVar.a.b> or IsDefined(myVar.a.b):

  1. Looks for myVar in an internal table of names (the symbol table).
  2. If myVar is the name of a complex object, including a scope, looks for an element named a in the object.

    3. If myVar is not the name of a complex object, it checks whether myVar.a is the name of a complex object and skips step 3.

  3. If myVar is the name of a complex object, it checks whether a is a complex object,
  4. If a or myVar.a is the name of a complex object, it checks whether b is the name of a simple variable, and returns the value of b.

    5. If myVar is a complex object but a is not a complex object, it checks whether a.b is the name of a simple variable and returns its value.

    If myVar.a is not a complex object, it checks whether myVar.a.B is the name of a simple variable and returns its value.

This way, even if myVar.a.b is a simple variable name, ColdFusion correctly resolves the variable name and can get its value.

You can also use array notation to get a simple variable with a name that includes periods. In this form of array notation, you use the scope name (or the complex variable that contains the simple variable) as the “array” name. You put the simple variable name, in single or double quotation marks, inside the square bracket.

Using array notation is more efficient than using plain dot notation because ColdFusion does not have to analyze and look up all the possible key combinations. For example, both of the following lines write the value of myVar.a.b, but the second line is more efficient than the first:

<cfoutput>myVar.a.b is: #myVar.a.b#<br></cfoutput>
<cfoutput>myVar.a.b is: #Variables["myVar.a.b"]#<br></cfoutput>


Setting a variable

ColdFusion cannot be as flexible when it sets a variable value as when it gets a variable, because it must determine the type of variable to create or set. Therefore, the rules for variable names that you set are stricter. Also, the rules vary depending on whether or not the first part of the variable name is the Cookie or Client scope identifier.

For example, assume you have the following code:

<cfset myVar.a.b = "This is a test">

If a variable myVar does not exist, it creates a structure named myVar, creates a structure named a in the structure myVar, creates a key named b in myVar.a, and gives it the value "This is a test". If either myVar or myVar.a exist and is not a structure, ColdFusion generates an error.

In other words, ColdFusion uses the same rules as in the Getting a variable section to resolve the variable name until it finds a name that does not exist yet. It then creates any structures that are needed to create a key named b inside a structure, and assigns the value to the key.

However, if the name before the first period is either Cookie or Client, ColdFusion uses a different rule. It treats all the text. including any periods, that follow the scope name as the name of a simple variable, because Cookie and Client scope variables must be simple. As a result if you have the following code, you see that ColdFusion creates a single, simple Client scope variable named myVar.a.b:

<cfset Client.myVar.a.b = "This is a test">
<cfdump var=#Client.myVar.a.b#>


Creating variables with periods

You should avoid creating the names of simple variables (including arrays) that include periods. However, ColdFusion provides mechanisms for handling cases where you must do so, for example, to maintain compatibility with names of variables in external data sources or to integrate your application with existing code that uses periods in variable names. The following sections describe how to create simple variable names that include periods.


Using brackets to create variables with periods

You can create a variable name that includes periods by using associative array structure notation, as described in Structure notation. To do so, you must do the following:

  • Refer to the variable as part of a structure. You can always do this, because ColdFusion considers all scopes to be structures. For more information on scopes, see About scopes
  • Put the variable name that must include a period inside square brackets and single or double quotation marks,

The following example shows this technique:

<cfset Variables['My.Variable.With.Periods'] = 12>
<cfset Request["Another.Variable.With.Periods"] = "Test variable">
<cfoutput>
   My.Variable.With.Periods is: #My.Variable.With.Periods#<br>
   Request.Another.Variable.With.Periods is:
      #Request.Another.Variable.With.Periods#<br>
</cfoutput>


Creating Client and Cookie variables with periods

To create a Client or Cookie variable with a name that includes one or more periods, simply assign the variable a value. For example, the following line creates a Cookie named User.Preferences.CreditCard:

<cfset Cookie.User.Preferences.CreditCard>


Data Type Conversion

ColdFusion automatically converts between data types to satisfy the requirements of an expression’s operations, including a function’s argument requirements. As a result, you generally don’t need to be concerned about compatibility between data types and the conversions from one data type to another. However, understanding how ColdFusion evaluates data values and converts data between types can help you prevent errors and code more effectively.


Operation-driven evaluation

Conventional programming languages enforce strict rules about mixing objects of different types in expressions. For example, in a language such as C++ or Basic, the expression ("8" * 10) produces an error because the multiplication operator requires two numerical operands and "8" is a string. When you program in such languages, you must convert between data types to ensure error-free program execution. For example, the previous expression might have to be written as (ToNumber("8") * 10).

In ColdFusion, however, the expression ("8" * 10) evaluates to the number 80 without generating an error. When ColdFusion processes the multiplication operator, it automatically attempts to convert its operands to numbers. Since "8" can be successfully converted to the number 8, the expression evaluates to 80.

ColdFusion processes expressions and functions in the following sequence:

  1. For each operator in an expression, it determines the required operands. (For example, the multiplication operator requires numeric operands and the CONTAINS operator requires string operands.)

    2. For functions, it determines the type required for each function argument. (For example, the Min function requires two numbers as arguments and the Len function requires a string.)

  2. It evaluates all operands or function arguments.
  3. It converts all operands or arguments whose types differ from the required type. If a conversion fails, it reports an error.


Conversion between types

Although the expression evaluation mechanism in ColdFusion is very powerful, it cannot automatically convert all data. For example, the expression "eight" * 10 produces an error because ColdFusion cannot convert the string "eight" to the number 8. Therefore, you must understand the rules for conversion between data types.

The following table explains how conversions are performed. The first column shows values to convert. The remaining columns show the result of conversion to the listed data type.

Value | As Boolean | As number | As date-time | As string
"Yes" | True | 1 | Error | "Yes"
"No" | False | 0 | Error | "No"
True | True | 1 | Error | "Yes"
False | False | 0 | Error | "No"
Number | True if Number is not 0, False otherwise. | Number | See “Date-time values” earlier in this chapter. | String representation of the number.
String | If "Yes" or "No", or if the string can be converted to a number, it is treated as listed above. | If it represents a number (for example, "1,000" or "12.36E-12"), it is converted to the corresponding number. If it represents a date-time (see next column), it is converted to the numeric value of the corresponding date-time object. | If it is an ODBC date, time, or timestamp (for example "{ts '2001-06-14 11:30:13'}", or if it is expressed in a standard US date or time format, including the use of full or abbreviated month names, it is converted to the corresponding date-time value. Days of week or unusual punctuation result in error. Dashes, forward-slashes, and spaces are generally allowed. | String
Date | Error | The numeric value of the date-time object. | Date | An ODBC timestamp.

ColdFusion cannot convert complex types, such as arrays, queries, and COM objects to other types. However, it can convert simple data elements of complex types to other simple data types.


Type conversion notes

The following sections detail specific rules and considerations for converting between types.


The cfoutput tag

The cfoutput tag always displays data as a string. As a result, when you display a variable using the cfoutput tag, ColdFusion applies the type conversion rules to any non-string data before displaying it. For example, the cfoutput tag displays a date-time value as an ODBC timestamp.


Case-insensitivity and Boolean conversion

Because ColdFusion expression evaluation is not case-sensitive, Yes, YES, and yes are equivalent; False, FALSE, and false are equivalent; No, NO, and no are equivalent; and True, TRUE, and true are equivalent.


Converting binary data

ColdFusion cannot automatically convert binary data to other data types. To convert binary data use the ToBase64 and ToString functions. For more information, see Binary Data Type and Base64 Encoding.


Converting date and time data

To ensure that a date and time value is expressed as a real number, add zero to the variable. The following example illustrates this:

<cfset mynow = now()>
Use cfoutput to display the result of the now function:<br>
<cfoutput>#mynow#</cfoutput><br>
Now add 0 to the result and display it again:<br>
<cfset mynow = mynow + 0>
<cfoutput>#mynow#</cfoutput>

At 5:34 PM on November 7, 2001, its output looked like this:

Using cfoutput to display the result of the now function:
{ts '2001-11-07 17:34:01'}
Now Add 0 to the result and display it:
37202.731956


Converting numeric values

When ColdFusion evaluates an expression that includes both integers and real numbers, the result is a real number. To convert a real number to an integer, use a ColdFusion function. The Int, Round, Fix, and Ceiling functions convert real numbers to integers, and differ in their treatment of the fractional part of the number.

If you use a hidden form field with a name that has the suffix _integer or _range to validate a form input field, ColdFusion truncates real numbers entered into the field and passes the resulting integer to the action page.

If you use a hidden form field with a name that has the suffix _integer, _float, or _range to validate a form input field, and the entered data contains a dollar amount (including a dollar sign) or a numeric value with commas, ColdFusion considers the input to be valid, removes the dollar sign or commas from the value, and passes the resulting integer or real number to the action page.


Evaluation and type conversion issues

The following sections explain several issues that you might encounter with type evaluation and conversion.


Comparing variables to True or False

You might expect the following two cfif tags to produce the same results:

<cfif myVariable>
<cfoutput>myVariable equals #myVariable# and is True
</cfoutput>
</cfif>
<cfif myVariable IS True>
<cfoutput>myVariable equals #myVariable# and is True
</cfoutput>
</cfif>

However, if myVariable has a numeric value such as 12, only the first example produces a result. In the second case, the value of myVariable is not converted to a Boolean data type, because the IS operator does not require a specific data type and just tests the two values for identity. Therefore, ColdFusion compares the value 12 with the constant True. The two are not equal, so nothing is printed. If myVariable is 1, "Yes", or True, however, both examples print the same result, because ColdFusion considers these to be identical to Boolean True.

If you use the following code, the output statement does display, because the contents of the variable, 12, is not equal to the Boolean value False.

<cfif myVariable IS NOT False>
<cfoutput>myVariable equals #myVariable# and IS NOT False
</cfoutput>
</cfif>

As a result, you should use the test <cfif testvariable>, and not use the IS comparison operator when testing whether a variable is True or False. Note that this issue is a case of the more general problem of ambiguous type expression evaluation, described in the following section.


Ambiguous type expressions and strings

When ColdFusion evaluates an expression that does not require strings, including all comparison operations, such as IS or GT, it checks whether it can convert each string value to a number or date-time object. If so, ColdFusion converts it to the corresponding number or date-time value (which is stored as a number). It then uses the number in the expression.

Short strings, such as 1a and 2P, can produce unexpected results. ColdFusion can interpret a single "a" as AM and a single "P" as PM. This can cause ColdFusion to interpret strings as date-time values in cases where this was not intended.

Similarly, if the strings can be interpreted as numbers, you might get unexpected results.

For example, ColdFusion interprets the following expressions as shown:

Interpreted as
<cfif "1a" EQ "01:00">
If 1:00am is 1:00am.
<cfif "1P" GT "2A">
If 1:00pm is later than 2:00am.
<cfset age="4a">
<cfset age=age + 7>
Treat the variable age as 4:00 am, convert it to the date-time value 0.16666666667, and add 7 to make it 7.16666666667.
<cfif "0.0" is "0">
If 0 is 0.

To prevent such ambiguities when you compare strings, use the ColdFusion string comparison functions Compare and CompareNoCase, instead of the comparison operators.

You can also use the IsDate function to determine whether a string can be interpreted as a date-time value, or to add characters to a string before comparison to avoid incorrect interpretation.


Date-time functions and queries when ODBC is not supported

Many CFML functions, including the Now, CreateDate, CreateTime, and CreateDateTime functions, return date-time objects. ColdFusion creates Open Database Connectivity (ODBC) timestamp values when it converts date-time objects to strings. As a result, you might get unexpected results when using dates with a database driver that does not support ODBC escape sequences., or when you use SQL in a query of queries.

If you use SQL to insert data into a database or in a WHERE clause to select data from a database, and the database driver does not support ODBC-formatted dates, use the DateFormat function to convert the date-time value to a valid format for the driver. This rule also applies to queries of queries.

For example, the following SQL statement uses the DateFormat function in a query of queries to select rows that have MyDate values in the future:

<cfquery name="MyQofQQ" dbtype="query">
SELECT *
FROM DateQuery
WHERE MyDate >= '#DateFormat(Now())#'
</cfquery>

The following query of queries fails with the error message “Error: {ts is not a valid date,” because the ColdFusion Now function returns an ODBC timestamp:

<cfquery name="MyQofQQ" dbtype="query">
SELECT *
FROM DateQuery
WHERE MyDate >= '#now()#'
</cfquery>


Using JavaCast with overloaded Java methods

You can overload Java methods so a class can have several identically named methods that differ only in parameter data types. At run time, the Java virtual machine (VM) attempts to resolve the specific method to use, based on the types of the parameters passed in the call. Because ColdFusion does not use explicit types, you cannot predict which version of the method the VM will use.

The ColdFusion JavaCast function helps you ensure that the right method executes by specifying the Java type of a variable, as in the following example:

<cfset  emp.SetJobGrade(JavaCast("int", JobGrade))>

The JavaCast function takes two parameters: a string representing the Java data type and the variable whose type you are setting. You can specify the following Java data types: bool, int, long, float, double, and String.

For more information on the JavaCast function, see the CFML Reference.


The effect of quotes

To ensure that ColdFusion properly interprets string data, surround strings in single or double quotes. For example, ColdFusion evaluates "10/2/2001" as a string that can be converted into a date-time object. However, it evaluates 10/2/2001 as a mathematical expression, 5/2001, which evaluates to 0.00249875062469.


Examples of type conversion in expression evaluation

The following examples demonstrate ColdFusion expression evaluation.


Example 1

2 * True + "YES" - ('y' & "es")

Result value as string: "2"

Explanation: (2*True) is equal to 2; ("YES"-"yes") is equal to 0; 2 + 0 equals 2.


Example 2

True AND 2 * 3

Result value as string: "YES"

Explanation: 6 is converted to Boolean True because it is non-zero; True AND True is True.


Example 3

"Five is " & 5

Result value as string: "Five is 5"

Explanation: 5 is converted to the string "5".


Example 4

DateFormat("October 30, 2001" + 1)

Result value as string: "31-Oct-01"

Explanation: The addition operator forces the string "October 30, 2001" to be converted to a date-time object and then to a number. The number is incremented by one. The DateFormat function requires its argument to be a date-time object; thus, the result of the addition is converted to a date-time object. One is added to the date-time object, moving it ahead by one day to October 31, 2001.


About scopes

Variables differ in the source of the data, the places in your code where they are meaningful, and how long their values persist. These considerations are generally referred to as a variable’s scope. Commonly used scopes include the Variables scope, the default scope for variables that you create, and the Request scope, which is available for the duration of an HTTP request.

Note: User-defined functions also belong to scopes. For more information on user-defined function scopes see Specifying the scope of a function.


Scope types

The following table lists the types of ColdFusion scopes and describes their uses.

Scope
Description
Variables (local)
The default scope for variables of any type that are created with the cfset and cfparam tags. A local variable is available only on the page on which it is created and any included pages (see also the Caller scope).
Form
Contains variables passed from a Form page to its action page as the result of submitting the form. (If you use the HTML form tag, you must use method="post".) For information on using the Form scope, see Retrieving and Formatting Data.
URL
Contains parameters passed to the current page in the URL that is used to call it. The parameters are appended to the URL in the format ?variablename = value[&variablename=value...]; for example www.MyCompany.com/inputpage.cfm?productCode=A12CD1510&
quantity=3.
Attributes
Used only in custom tag pages. Contains the values passed by the calling page in the custom tag’s attributes. For information on using the Attributes scope, see Creating and Using Custom CFML Tags.
Caller
Used only in custom tag pages. The custom tag’s Caller scope is a reference to the calling page’s Variables scope. Any variables that you create or change in the custom tag page using the Caller scope are visible in the calling page’s Variables scope. For information on using the Caller scope, see Creating and Using Custom CFML Tags
ThisTag
Used only in custom tag pages. The ThisTag scope is active for the current invocation of the tag. If a custom tag contains a nested tag, any ThisTag scope values you set before calling the nested tag are preserved when the nested tag returns to the calling tag.
The ThisTag scope includes three built-in variables that identify the tag’s execution mode, contain the tag’s generated contents, and indicate whether the tag has an end tag.
A nested custom tag can use the cfassociate tag to return values to the calling tag’s ThisTag scope. For more information on the ThisTag scope, see Accessing tag instance data.
Request
Used to hold data that must be available for the duration of one HTTP request. The Request scope is available to all pages, including custom tags and nested custom tags, that are processed in response to the request.
This scope is useful for nested (child/parent) tags. This scope can often be used in place of the Application scope, to avoid the need for locking variables. Several chapters discuss using the Request scope.
CGI
Contains environment variables identifying the context in which a page was requested. The variables available depend on the browser and server software. For a list of the commonly used CGI variables, see the CFML Reference.
Cookie
Contains variables maintained in a user’s browser as cookies. Cookies are typically stored in a file on the browser, so they are available across browser sessions and applications. You can create memory-only Cookie variables, which are not available after the user closes the browser. Cookie scope variable names can include periods.
Client
Contains variables that are associated with one client. Client variables let you maintain state as a user moves from page to page in an application, and are available across browser sessions. By default, Client variables are stored in the system registry, but you can store them in a cookie or a database. Client variables cannot be complex data types and can include periods in their names. For information on using the Client scope, see Using Persistent Data and Locking
Session
Contains variables that are associated with one client and persist only as long as the client maintains a session. They are stored in the server’s memory and can be set to time out after a period of inactivity. You cannot use Session variables on server clusters where more than one computer can process requests from a single session. For information on using the Session scope, see Using Persistent Data and Locking
Application
Contains variables that are associated with one, named application on a server. The cfapplication tag name attribute specifies the application name. For information on using the Application scope, see Using Persistent Data and Locking
Server
Contains variables that are associated with the current ColdFusion Server. This scope lets you define variables that are available to all your ColdFusion pages, across multiple applications. For information on using the Server scope, see Using Persistent Data and Locking
Flash
Variables sent by a Macromedia Flash movie to ColdFusion and returned by ColdFusion to the movie. For more information on the Flash scope, see Using the Flash Remoting service
Arguments
Variables passed in a call to a user-defined function or ColdFusion component method. For more information see About the Arguments scope.
This
Variables that are declared inside a ColdFusion component or in a cffunction tag that is not part of a ColdFusion component. These variables exist only while a function executes. For information on using the This scope, see Creating and Using Custom CFML Tags.
function local
Contains variables that are declared inside a user-defined function that you create using CFScript and exist only while a function executes. For information on using function local variables, see Writing and Calling User-Defined Functions

Caution:To prevent data corruption, you lock code that uses Session, Application, or Server scope variables. For more information on using these scopes and locking access to code, see Using Persistent Data and Locking.


Creating and using variables in scopes

The following table shows how you create and refer to variables in different scopes in your code. For more information on the mechanisms for creating variables in most scopes, see Creating Variables.

Scope prefix (type) | Prefix required to reference | Where available | Created by
Variables (Local) | No | On the current page. Cannot be accessed by a form’s action page (unless the form page is also the action page). Variables in this scope used on a page that calls a custom tag can be accessed in the custom tag by using its Caller scope; however, they are not available to any nested custom tags. | Specifying the prefix Variables, or using no prefix, when you create the variable.
Form | No | On the action page of a form and in custom tags called by the action page; cannot be used on a form page that is not also the action page. | A form or cfform tag. Contains the values of form field tags (such as input) in the form body when the form is submitted. The variable name is the name of the form field.
URL | No | On the target page of the URL. | The system. Contains the parameters passed in the URL query string used to access the page.
Attributes | Yes | On the custom tag page. | The calling page passing the values to a custom tag page in the custom tag’s attributes.
Caller | On the custom tag page, Yes. On the calling page, No (Variables prefix is optional). | On the custom tag page, by using the Caller scope prefix. On the page that calls the custom tag, as local variables (Variables scope). | On the custom tag page, by specifying the prefix Caller when you create the variable. On the calling page, by specifying the prefix Variables, or using no prefix, when you create the variable.
ThisTag | Yes | On the custom tag page. | Specifying the prefix ThisTag when you create the variable in the tag or using the cfassociate tag in a nested custom tag.
Request | Yes | On the creating page and in any pages invoked during the current HTTP request after the variable is created, including in custom tags and nested custom tags. | Specifying the prefix Request when you create the variable.
CGI | No | On any page. Values are specific to the latest browser request. | The Web server. Contains the server environment variables that result from the browser request.
Cookie | No | For one client in one or more applications and pages, over multiple browser sessions. | A cfcookie tag. You can also set memory-only cookies by specifying the prefix Cookie when you create the variable.
Client | No | For one client in one application, over multiple browser sessions. | Specifying the prefix Client when you create the variable.
Session | Yes | For one client in one application and one browser session. Surround all code that uses Session variables in cflock blocks. | Specifying the prefix Session when you create the variable.
Application | Yes | For multiple clients in one application over multiple browser sessions. Surround all code that uses Application variables in cflock blocks. | Specifying the prefix Application when you create the variable.
Server | Yes | To any page on the ColdFusion Server. Surround all code that uses Server variables in cflock blocks. | Specifying the prefix Server when you create the variable.
Flash | Yes | A ColdFusion page or ColdFusion component called by a flash client | The ColdFusion Client access. You assign a value to Flash.You can assign values to the Flash.result and Flash.pagesize variables.
Arguments | No | Within the body of a user-defined function or ColdFusion component method. | The calling page passing an argument in the function call.
This | Yes | Within the body of a user-defined function or ColdFusion component method that was created using the cffunction tag, only while the function executes. | Specifying the prefix This when you create the variable.
(function local, no prefix) | Prohibited | Within the body of a user-defined function that was created using CFScript, only while the function executes. | A var statement in the function body.


Using Scopes

The following sections provide details on how you can create and use variables in different scopes.


Evaluating unscoped variables

If you use a variable name without a scope prefix, ColdFusion checks the scopes in the following order to find the variable:

  1. Arguments
  2. Variables (local scope)
  3. CGI
  4. URL
  5. Form
  6. Cookie
  7. Client

Because ColdFusion must search for variables when you do not specify the scope, you can improve performance by specifying the scope for all variables.

To access variables in all other scopes, you must prefix the variable name with the scope identifier.


Scopes and CFX tags

ColdFusion scopes do not apply to CFX tags, custom tags that you write in a programming language such as C++ or Java. The ColdFusion page that calls a CFX tag must use tag attributes to pass data to the CFX tag. The CFX tag must use the Java Request and Response interfaces or the C++ Request class to get and return data.

The Java setVariable Response interface method and C++ CCFX::SetVariable method to return data to the Variables scope of the calling page. Therefore, they are equivalent to setting a Caller scope variable in a custom ColdFusion tag.


Using scopes as structures

ColdFusion makes all named scopes available as structures. You cannot access the function-local scope for UDFs that you define using CFScript as a structure. (In ColdFusion 4.5 and 5, the following scopes are not available as structures: Variables, Caller, Client, Server.)

You can reference the variables in these scopes as elements of a structure. To do so, specify the scope name as the structure name and the variable name as the key. For example, if you have a MyVar variable in the Request scope, you can refer to either of the following ways:

Request.MyVar
Request["MyVar"]

Similarly, you can use CFML structure functions to manipulate the contents of the scope. For more information on using structures, see Using Arrays and Structures.

Caution:Do not call StructClear(Session) to clear session variables. This deletes the SessionID, CFID, and CFtoken built-in variables, effectively ending the session. If you want to use StructClear to delete your Session variables, put those variables in a structure in the Session scope, then clear that structure. For example, put all your Session variables in Session.MyVars and then call StructClear(Session.Myvars) to clear the variables.


Ensuring Variable Existence

ColdFusion generates an error if you try to use a variable value that does not exist. Therefore, before you use any variable whose value is assigned dynamically, you must ensure that a variable value exists. For example, if your application has a form, it must use some combination of requiring users to submit data in fields, providing default values for fields, and checking for the existence of field variable values before they are used.

There are several ways to ensure that a variable exists before you use it, including:

  • You can use the IsDefined function to test for the variable’s existence.
  • You can use the cfparam tag to test for a variable and set it to a default value if it does not exist.

You can also use a cfform input tag with a hidden attribute to tell ColdFusion to display a helpful message to any user who does not enter data in a required field. For more information on this technique, see Requiring users to enter values in form fields.


Testing for a variable's existence

Before relying on a variable's existence in an application page, you can test to see if it exists by using the IsDefined function.

For example, if you submit a form with an unsettled check box, the action page does not get a variable for the check box. The following example from a form action page makes sure the Contractor check box Form variable exists before using it:

<cfif IsDefined("Form.Contractor")>
   <cfoutput>Contractor: #Form.Contractor#</cfoutput>
</cfif>

You must always enclose the argument passed to the IsDefined function in double quotes. For more information on the IsDefined function, see the CFML Reference.

If you attempt to evaluate a variable that you did not define, ColdFusion cannot process the page and displays an error message. To help diagnose such problems, use the interactive debugger in ColdFusion Studio or turn on debugging in the ColdFusion Administrator. The Administrator debugging information shows which variables are being passed to your application pages.


Variable existence notes

If a variable is part of a scope that is available as a structure, you might get a minor performance increase by testing the variable’s existence using the StructKeyExists function instead of the IsDefined function.

You can also determine which Form variables exist by inspecting the contents of the Form.fieldnames built-in variable. This variable contains a list of all the filed submitted by the form. Remember, however, that form Text fields are always submitted to the action page, and may contain an empty string if the user did not enter data.

The IsDefined function always Returns False if you specify an array or structure element using bracket notation. For example IsDefined("myArray[3]") always returns False, even if the array element myArray[3] has a value. To check for the existence of an array element, copy the element to a simple variable and use IsDefined to test whether the simple variable exists.


Using the cfparam tag

You can ensure that a variable exists by using the cfparam tag, which tests for the variable’s existence and optionally supplies a default value if the variable does not exist. The cfparam tag has the following syntax:

<cfparam name="VariableName"
   type="data_type"
   default="DefaultValue">

Note: For information on using the type attribute to validate the parameter data type, see the CFML Reference.

There are two ways to use the cfparam tag to test for variable existence, depending on how you want the validation test to proceed:

  • With only the name attribute to test that a required variable exists. If it does not exist, the ColdFusion Server stops processing the page and displays an error message.
  • With the name and default attributes to test for the existence of an optional variable. If the variable exists, processing continues and the value is not changed. If the variable does not exist, it is created and set to the value of the default attribute, and processing continues.

The following example shows how to use the cfparam tag to check for the existence of an optional variable and to set a default value if the variable does not already exist:

<cfparam name="Form.Contract" default="Yes">


Example: testing for variables

Using the cfparam tag with the name attribute is one way to clearly define the variables that a page or a custom tag expects to receive before processing can proceed. This can make your code more readable, as well as easier to maintain and debug.

For example, the following cfparam tags indicate that this page expects two form variables named StartRow and RowsToFetch:

<cfparam name="Form.StartRow">
<cfparam name="Form.RowsToFetch">

If the page with these tags is called without either one of the form variables, an error occurs and the page stops processing. By default, ColdFusion displays an error message; you can also handle the error as described in Handling Errors.


Example: setting default values

The following example uses the cfparam tag to see if optional variables exist. If they do exist, processing continues. If they do not exist, the ColdFusion Server creates them and sets them to the default values.

<cfparam name="Cookie.SearchString" default="temple">
<cfparam name="Client.Color" default="Grey">
<cfparam name="ShowExtraInfo" default="No">

You can use cfparam to set default values for URL and Form variables, instead of using conditional logic. For example, you could include the following code on the action page to ensure that a SelectDepts variable exists:

<cfparam name="Form.SelectedDepts" default="Marketing,Sales">


Validating Data Types

It is often not sufficient that input data merely exists; it must also have the right format. For example, a date field must have data in a date format. A salary field must have data in a numeric or currency format. There are many ways to ensure the validity of data, including the following methods:

  • Use the cfparam tag with the type attribute to validate any variable.
  • Use a form input tag with a hidden attribute to validate the contents of a form input field. For information on this technique, see Validating form field data types.
  • Use cfform controls that have validation attributes. For information on using cfform tags, see Building Dynamic Forms.
  • Use the cfqueryparam tag in a SQL WHERE clause to validate query parameters. For information on this technique, see Using cfqueryparam.

Note:

Data validation using the cfparam, cfqueryparam, and form tags is done by the server. Validation using cfform tags is done using JavaScript in the user’s browser, before any data is sent to the server.


Using cfparam to validate the data type

The cfparam type attribute lets you validate the type of a parameter. You can specify that the parameter type must be any of the following values:

Type value | Meaning
any | any value
array | any array value
binary | any binary value
boolean | true, false, yes, or no
date | any value in a valid date, time, or date-time format
numeric | any number
query | a query object
string | a text string or single character
struct | a structure
UUID | a Universally Unique Identifier (UUID) formatted as XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXX where X stands for a hexadecimal digit (0-9 or A-F).
variableName | a valid variable name

For example, you can use the following code to validate the variable BirthDate:

<cfparam name="BirthDate" type="date">

If the variable is not in a valid date format, an error occurs and the page stops processing.


Passing Variables to Custom Tags and UDFs

The following sections describe rules for how data gets passed to custom tags and user-defined functions that are written in CFML, and to CFX custom tags that are written in Java or C++.


Passing Variables to CFML tags and UDFs

When you pass a variable to a CFML custom tag as an attribute, or to a user-defined function as an argument, the following rules determine whether the custom tag or function receives its own private copy of the variable or only gets a reference to the calling page's variable:

  • Simple variables and arrays are passed as copies of the data. If your argument is an expression that contains multiple simple variables, the result of the expression evaluation is copied to the function or tag.
  • Structures, queries, and cfobject objects are passed as references to the object.

If the tag or function gets a copy of the calling page’s data, changes to the variable in the custom tag or function do not change the value of the variable on the calling page. If the variable is passed by reference, changes to the variable in the custom tag or function also change the value of the variable in the calling page.

To pass a variable to a custom tag, you must put the variable name in pound signs. To pass a variable to a function, do not put the variable name in pound signs. For example, the following code calls a user-defined function using three Form variables:

<cfoutput>
TOTAL INTEREST: #TotalInterest(Form.Principal, Form.AnnualPercent,
Form.Months)#<br>
</cfoutput>

The following example calls a custom tag using two variables, MyString and MyArray:

<cf_testTag stringval=#MyString# arrayval=#MyArray#>


Passing Variables to CFX Tags

You cannot pass arrays, structures, or cfobject objects to CFX tags. You can pass a query to a CFX tag by using the query attribute when calling the tag. ColdFusion normally converts simple data types to strings when passing them to CFX tags; however, the Java Request Interface getIntAttribute method allows you to get a passed integer value.

  Previous


Using Expressions and Pound Signs

This chapter discusses how to use expressions in CFML. It discusses the elements of ColdFusion Expressions and how to create expressions. It also describes the correct use of pound signs to indicate expressions in ColdFusion tags such as cfoutput, in strings, and in expressions. Finally, it describes how to use variables in variable names and strings to create dynamic expressions, and dynamic variables.

Contents
  • Expressions
  • Using Pound Signs
  • Dynamic Expressions and Dynamic Variables
Next


Expressions

ColdFusion expressions consist of operands and operators. Operands are comprised of constants and variables. Operators, such as the multiplication symbol, are the verbs that act on the operands; functions are a form of operator.

The simplest expression consists of a single operand with no operators. Complex expressions have multiple operators and operands. The following are all ColdFusion Expressions:

12
MyVariable
(1 + 1)/2
"father" & "Mother"
Form.divisor/Form.dividend
Round(3.14159)

Operators act on the operands. Some operators, such as functions with a single argument, take a single operand. Many operators, including most arithmetic and logical operators, take two operands. The following is the general form of a two-operand expression:

Expression Operator Expression

Note that the operator is surrounded by expressions. Each expression can be a simple operand (variable or constant) or a subexpression consisting of more operators and expressions. Complex expressions are built up using subexpressions. For example, in the expression (1 + 1)/2, 1 + 1 is a subexpression consisting of an operator and two operands.


Operator types

ColdFusion has four types of operators:

  • Arithmetic
  • Boolean
  • Decision (or comparison)
  • String

Functions also can be viewed as operators because they act on operands.


Arithmetic operators

The following table describes the arithmetic operators:

Operator | Description
+ - * / | Basic arithmetic: addition, subtraction, multiplication, and division. In division, the right operand cannot be zero.
+ - | Unary arithmetic: Set the sign of a number.
MOD | Modulus: Return the remainder after a number is divided by a divisor. The result has the same sign as the divisor. The right should be an integer; using an integer causes an error, and if you specify a real number ColdFusion ignores the fractional part. For example, 11 MOD 4 is 3.
\ | Integer division: Divide an integer by another integer. Use the backslash character (\) to separate the integers. The right operand cannot be zero. For example, 9\4 is 2.
^ | Exponentiation: Return the result of a number raised to a power (exponent). Use the caret character (^) to separate the number from the power. For example, 2^3 is 8. Real and negative numbers are allowed for both the base and the exponent. However, any expression that equates to an imaginary number, such -1^.5 results in the string "-1.#IND. ColdFusion does not support imaginary or complex numbers.


Boolean operators

Boolean, or logical, operators perform logical connective and negation operations. The operands of Boolean operators are Boolean (True/False) values.The following table describes the Boolean operators

Operator | Description
NOT | Reverse the value of an argument. For example, NOT True is False and vice versa.
AND | Return True if both arguments are True; return False otherwise. For example, True AND True is True, but True AND False is False.
OR | Return True if any of the arguments is True; return False otherwise. For example, True OR False is True, but False OR False is False.
XOR | Exclusive or: Return True if one of the values is True and the other is False. Return False if both arguments are True or both are False. For example, True XOR True is False, but True XOR False is True.
EQV | Equivalence: Return True if both operands are True or both are False. The EQV operator is the opposite of the XOR operator. For example, True EQV True is True, but True EQV False is False.
IMP | Implication: The statement A IMP B is the equivalent of the logical statement “If A Then B.” A IMP B is False only if A is True and B is False. It is True in all other cases.


Decision operators

ColdFusion’s decision, or comparison, operators produce a Boolean True/False result. The following table describes the decision operators:

Operator | Description
IS | Perform a case-insensitive comparison of two values. Return True if the values are identical.
IS NOT | Opposite of IS. Perform a case-insensitive comparison of two values. Return True if the values are not identical.
CONTAINS | Return True if the value on the left is contained in the value on the right.
DOES NOT CONTAIN | Opposite of CONTAINS. Return True if the value on the left is not contained in the value on the right.
GREATER THAN | Return True if the value on the left is greater than the value on the right.
LESS THAN | Opposite of GREATER THAN. Return True if the value on the left is smaller than the value on the right.
GREATER THAN OR EQUAL TO | Return True if the value on the left is greater than or equal to the value on the right.
LESS THAN OR EQUAL TO | Return True if the value on the left is less than or equal to the value on the right.


Alternative notation for decision operators

You can replace some decision operators with alternative notations to make your CFML more compact, as shown in the following table.

Operator | Alternative name(s)
IS | EQUAL, EQ
IS NOT | NOT EQUAL, NEQ
GREATER THAN | GT
LESS THAN | LT
GREATER THAN OR EQUAL TO | GTE, GE
LESS THAN OR EQUAL TO | LTE, LE


Decision operator rules

The following rules apply to decision operators:

  • When ColdFusion evaluates an expression that contains a decision operator other than CONTAINS or DOES NOT CONTAIN, it first determines if the data can be converted to numeric values. If they can be converted, it performs a numeric comparison on the data. If they cannot be converted, it performs a string comparison. This can sometimes result in unexpected results. For more information on this behavior, see Evaluation and type conversion issues.
  • When ColdFusion evaluates an expression with CONTAINS or DOES NOT CONTAIN it does a string comparison. The expression A CONTAINS B evaluates to True if B is a substring of A. Therefore an expression such as the following evaluates as True:
    • 123.45 CONTAINS 3.4
  • When a ColdFusion decision operator compares strings, it ignores the case. As a result, the following expression is True:
    • "a" IS "A"
  • When a ColdFusion decision operator compares strings, it evaluates the strings from left to right, comparing the characters in each position according to their sorting order. The first position where the characters differ determines the relative values of the strings. As a result, the following expressions are True:
    • "ab" LT "aba"
"abde" LT "ac"


String operators

There is one string operator, which is the concatenation operator.

Operator | Description
& | Concatenates strings.


Operator precedence and evaluation ordering

The order of precedence controls the order in which operators in an expression are evaluated. The order of precedence is as follows:

Unary +, Unary -
^
*, /
\
MOD
+, -
&
EQ, NEQ, LT, LTE, GT, GTE, CONTAINS, DOES NOT CONTAIN
NOT
AND
OR
XOR
EQV
IMP

To enforce a non-standard order of evaluation, you must parenthesize expressions. For example:

  • 6 - 3 * 2 is equal to 0
  • (6 - 3) * 2 is equal to 6

You can nest parenthesized expressions. When in doubt about the order in which operators in an expression will be evaluated, use parentheses to force the order of evaluation.


Using functions as operators

Functions are a form of operator. Because ColdFusion functions return values, you can use function results as operands. Function arguments are expressions. For example, the following are valid expressions:

  • Rand()
  • UCase("This is a text: ") & ToString(123 + 456)


Function syntax

The following table shows function syntax and usage guidelines:

Usage
Example
No arguments
Function()
Basic format
Function(Data)
Nested functions
Function1(Function2(Data))
Multiple arguments
Function(Data1, Data2, Data3)
String arguments
Function('This is a demo')
Function("This is a demo")
Arguments that are expressions
Function1(X*Y, Function2("Text"))

All functions return values. In the following example, the cfset tag sets a variable to the value returned by the Now function:

<cfset myDate = DateFormat(Now(), "mmmm d, yyyy")>

You can use the values returned by functions directly to create more complex expressions, as in the following example:

Abs(Myvar)/Round(3.14159)

For more information on how to insert functions in expressions, see Using Pound Signs.


Optional function arguments

Some functions take optional arguments after their required arguments. If omitted, all optional arguments default to a predefined value. For example:

  • Replace("Eat and Eat", "Eat", "Drink") returns "Drink and Eat"
  • Replace("Eat and Eat", "Eat", "Drink", "All") returns "Drink and Drink"

The difference in the results is because the Replace function takes an optional fourth argument that specifies the scope of replacement. The default value is "One," which explains why only the first occurrence of "Eat" was replaced with "Drink" in the first example. In the second example, a fourth argument causes the function to replace all occurrences of "Eat" with "Drink".


Expression evaluation and functions

It is important to remember that ColdFusion evaluates function attributes as expressions before it executes the function. As a result, you can use any ColdFusion expression as a function attribute. For example, consider the following lines:

<cfset firstVariable = "we all need">
<cfset myStringVar = UCase(firstVariable & " more sleep!")>

When ColdFusion Server executes the second line, it does the following:

  1. Determines that there is an expression with a string concatenation.
  2. Evaluates the firstVariable variable as the string "we all need".
  3. Concatenates "we all need" with the string " more sleep!" to get "we all need more sleep!".
  4. Passes the string "we all need more sleep!" to the UCase function.
  5. Executes the UCase function on the string argument "we all need more sleep!" to get "WE ALL NEED MORE SLEEP!".
  6. Assigns the string value "WE ALL NEED MORE SLEEP!" to the variable myStringVar.

ColdFusion completes Steps 1-–3 before invoking the function.


Using Pound Signs

Pound signs (#) have a special meaning in CFML. When the ColdFusion Server encounters pound signs in CFML text, such as the text in a cfoutput tag body, it checks to see if the text between the pound signs is either a variable or a function.

Is so, it replaces the text and surrounding pound signs with the variable value or the result of the function. Otherwise, ColdFusion generates an error.

For example, to output the current value of a variable named Form.MyFormVariable, you delimit (surround) the variable name with pound signs:

<cfoutput>Value is #Form.MyFormVariable#</cfoutput>

In this example, the variable Form.MyFormVariable is replaced with the value assigned to it.

Follow these guidelines when using pound signs:

  • Use pound signs to distinguish variables or functions from plain text.
  • Surround only a single variable or function in pound signs; for example, #Variables.myVar# or #Left(myString, position)#. (However, a function in pound signs can contain nested functions, such as #Left(trim(myString), position)#.
  • Do not put complex expressions, such as 1 + 2 in pound signs.
  • Use pound signs only where necessary, because unneeded pound signs slow processing.

The following sections provide more details on how to use pound signs in CFML. For a description of using pound signs to create variable names, see Using pound signs to construct a variable name in assignments


Using pound signs in ColdFusion tag attribute values

You can put variables, functions, or expressions inside tag attributes by enclosing the variable or expression with pound signs. For example, if the variable CookieValue has the value "MyCookie", the following line sets the cfcookie value attribute to "The value is MyCookie":

<cfcookie name="TestCookie" value="The value is #CookieValue#">

You can optionally omit quotes around variables used as attribute values as shown in the following example:

<cfcookie name = TestCookie value = #CookieValue#>

However, surrounding all attribute values in quotes is more consistent with HTML coding style.

If you use string expressions to construct an attribute value, as shown in the following example, the strings inside the expression use single quotation marks (’) to differentiate the quotes from the quotation marks that surround the attribute value.

<cfcookie name="TestCookie2" value="The #CookieValue & 'ate the cookie!'#">

Note: You do not need to use pound signs when you use the cfset tag to assign one variable’s value to another value. For example, the following tag assigns the value of the oldVar variable to the new variable, newVar: <cfset newVar = oldVar>.


Using pound signs in tag bodies

You can put variables or functions freely inside the bodies of the following tags by enclosing each variable or expression with pound signs:

  • cfoutput
  • cfquery
  • cfmail

For example:

<cfoutput>
   Value is #Form.MyTextField#
</cfoutput>

<cfoutput>
   The name is #FirstName# #LastName#.
</cfoutput>

<cfoutput>
   The value of Cos(0) is #Cos(0)#
</cfoutput>

If you omit the pound signs, the text, rather than the value, appears in the output generated by the cfoutput statement.

Two expressions inside pound signs can be adjacent to one another, as in the following example:

<cfoutput>
   "Mo" and "nk" is #Left("Moon", 2)##Mid("Monkey", 3, 2)#
</cfoutput>

This code displays the following text:

"Mo" and "nk" is Monk

Note that ColdFusion does not interpret the double pound sign as an escaped # character.


Using pound signs in strings

You can put variables or functions freely inside strings by enclosing each variable or expression with pound signs. For example:

<cfset TheString = "Value is #Form.MyTextField#">
<cfset TheString = "The name is #FirstName# #LastName#.">
<cfset TheString = "Cos(0) is #Cos(0)#">

ColdFusion automatically replaces the text with the value of the variable or the value returned by the function. For example, the following pairs of cfset statements produce the same result:

<cfset TheString = "Hello, #FirstName#!">
<cfset TheString = "Hello, " & FirstName & "!">

If pound signs are omitted inside the string, the text, rather than the value, appears in the string. For example, the following pairs of cfset statements produce the same result:

<cfset TheString = "Hello, FirstName!">
<cfset TheString = "Hello, " & "First" & "Name!">

As with the cfoutput statement, two expressions can be adjacent to each other in strings, as in the following example:

<cfset TheString = "Monk is #Left("Moon", 2)##Mid("Monkey", 3, 2)#">

The double quotes around "Moon" and "Monkey" do not need to be escaped (as in ""Moon"" and ""Monkey""). This is because the text between the pound signs is treated as an expression; it is evaluated before its value is inserted inside the string.


Nested pound signs

In a few cases, you can nest pound signs in an expression. The following example uses nested pound signs:

<cfset Sentence = "The length of the full name is
#Len("#FirstName# #LastName#")#">

In this example, pound signs are nested so that the values of the variables FirstName and LastName are inserted in the string whose length the Len function calculates.

Nested pound signs imply a complex expression that can typically be written more clearly and efficiently without the nesting. For example, you can rewrite the preceding code example without the nested pound signs, as follows:

<cfset Sentence2 = "The length of the full name is #Len(FirstName & " "
& LastName)#">

The following achieves the same results and can further improve readability:

<cfset FullName = "#FirstName# #LastName#">
<cfset Sentence = "The length of the full name
   is #Len(FullName)#">

A common mistake is to put pound signs around the arguments of functions, as in:

<cfset ResultText = "#Len(#TheText#)#">
<cfset ResultText = "#Min(#ThisVariable#, 5 + #ThatVariable#)#">
<cfset ResultText = "#Len(#Left("Some text", 4)#)#">

These statements result in errors. As a general rule, never put pound signs around function arguments.


Using pound signs in expressions

Use pound signs in expressions only when necessary, because unneeded pound signs reduce clarity and can increase processing time. The following example shows the preferred method for referencing variables:

<cfset SomeVar = Var1 + Max(Var2, 10 * Var3) + Var4>

In contrast, the following example uses pound signs unnecessarily and is less efficient than the previous statement:

<cfset #SomeVar# = #Var1# + #Max(Var2, 10 * Var3)# + #Var4#>


Dynamic Expressions and Dynamic Variables

This section discusses the advanced topics of dynamic expressions, dynamic evaluation, and dynamic variable naming. Many ColdFusion programmers never encounter or need to use dynamic expressions. However, dynamic variable naming is important in situations where the variable names are not known in advance, such as in shopping cart applications.

This section also discusses the use of the IIF function which is most often used without dynamic expressions. This function dynamically evaluates its arguments, and you must often use the DE function to prevent the evaluation. For more information on using the IIF function, see Using the IIF function .

Note: This section uses several tools and techniques that are documented in later chapters. If you are unfamiliar with using ColdFusion forms, structures, and arrays, you should learn about these tools before reading this section.


About dynamic variables

Dynamic variables are variables that are named dynamically, typically by creating a variable name from a static part and a variable part. For example, the following example dynamically constructs the variable name from a variable prefix and a static suffix:

<cfset "#flavor#_availability" = "out of stock">

Using dynamic variables in this manner does not require dynamic evaluation.


About dynamic expressions and dynamic evaluation

In a dynamic expression, the actual expression, not just its variable values, is determined at execution time. In other words, in a dynamic expression the structure of the expression, such as the names of the variables, not just the values of the variables, gets built at run time.

You create dynamic expressions using string expressions, which are expressions contained in strings, (that is, surrounded with quotation marks). Dynamic evaluation is the process of evaluating a string expression. The Evaluate and IIF functions, and only these functions, perform dynamic evaluation.

When ColdFusion performs dynamic evaluation it does the following:

  1. Takes a string expression and treats it as a standard expression, as if the expression was not a string.
  2. Parses the expression to determine the elements of the expression and validate the expression syntax.
  3. Evaluates the expression, looking up any variables and replacing them with their values, calling any functions, and performing any required operations.

This process enables ColdFusion to interpret dynamic expressions with variable parts. However, it incurs a substantial processing overhead.

Dynamic expressions were important in early versions of ColdFusion, before it supported arrays and structures, and they still can be useful in limited circumstances. However, the ability to use structures and the ability to use associative array notation to access structure elements provide more efficient and easier methods for dynamically managing data. For information on using arrays and structures, see Using Arrays and Structures.


Selecting how to create variable names

The following two examples show cases where you need dynamic variable names:

  • Form applications where the number and names of fields on the form vary dynamically. In this case, the form posts only the names and values of its fields to the action page. The action page does not know all the names of the fields, although it does know how the field names (that is, the variable names) are constructed.
  • If the following are true:
    • ColdFusion calls a custom tag multiple times
    • the custom tag result must be returned to different variables each time
    • the calling code can specify the variable in which to return the custom tag result.
      • In this case, the custom tag does not know the return variable name in advance, and gets it as an attribute value.

In both cases, it might appear that dynamic expressions using the Evaluate function are needed to construct the variable names. However, you can achieve the same ends more efficiently by using dynamic variable naming, as shown in Example: a dynamic shopping cart.

This does not mean that you must always avoid dynamic evaluation. However, given the substantial performance costs of dynamic evaluation, you should first ensure that one of the following techniques cannot serve your purpose:

  • An array (using index variables)
  • Associative array references containing expressions to access structure elements
  • Dynamically generated variable names


Dynamic variable naming without dynamic evaluation

While ColdFusion does not always allow you to construct a variable name in-line from variable pieces, it does let you to do so in the most common uses, as described in the following sections.


Using pound signs to construct a variable name in assignments

You can combine text and variable names to construct a variable name on the left side of a cfset assignment. For example, the following code sets the value of the variable Product12 to the string "Widget":

<cfset ProdNo = 12>
<cfset "Product#ProdNo#" = "Widget">

To construct a variable name this way, all the text on the left side of the equal sign must be in quotation marks.

This usage is less efficient than using arrays. The following example has the same purpose as the previous one, but requires less processing:

<cfset MyArray=ArrayNew(1)>
<cfset prodNo = 12>
<cfset myArray[prodNo] = "Widget">


Dynamic variable limitation

When you use a dynamic variable name in quotes on the left side of an assignment, the name must be either a simple variable name or a complex name that uses object.property notation (such as MyStruct.#KeyName#). You cannot use an array as part of a dynamic variable name. For example, the following code generates an error:

<cfset MyArray=ArrayNew(1)>
<cfset productClassNo = 1>
<cfset productItemNo = 9>
<cfset "myArray[#productClassNo##productItemNo#]" = "Widget">

However, you can construct an array index value dynamically from variables without using quotes on the left side of an assignment. For example, the preceding sample code works if you replace the final line with the following line:

<cfset myArray[#productClassNo# & #productItemNo#] = "Widget">


Dynamically constructing structure references

The ability to use associative array notation to reference structures provides a way for you to use variables to dynamically create structure references. (For a description of associative array notation, see Structure notation.) Associative array structure notation allows you to use a ColdFusion expression inside the index brackets. For example, if you have a productName structure with keys of the form product_1, product_2 and so on, you can use the following code to display the value of productName.product_3:

<cfset prodNo = 3>
<cfoutput>
   Product_3 Name: #ProductName["product_" & prodNo]#
<cfoutput>

For an example of using this format to manage a shopping cart, see Example: a dynamic shopping cart.


Using dynamic evaluation

The following sections describe how to use dynamic evaluation and create dynamic expressions.


ColdFusion dynamic evaluation functions

The following table describes the functions that perform dynamic evaluation and are useful in evaluating dynamic expressions:

Function | Purpose
DE | Escapes any double quotes in the argument and wraps the result in double quotes. The DE function is particularly useful with the IIF function, to prevent the function from evaluating a string to be output. For an example of using the DE function with the IIF function, see Using the IIF function.
Evaluate | Takes one or more string expressions and dynamically evaluates their contents as expressions from left to right. (The results of an evaluation to the left can have meaning in an expression to the right.) Returns the result of evaluating the rightmost argument. For more information on this function see About the Evaluate function.
IIF | Evaluates a boolean condition expression. Depending on whether this expression is True or False, dynamically evaluates one of two string expressions and returns the result of the evaluation. The IIF function is convenient for incorporating a cfif tag in-line in HTML. For an example of using this function, see Using the IIF function.
SetVariable | Sets a variable identified by the first argument to the value specified by the second argument. This function is no longer required in well-formed ColdFusion pages; see SetVariable function considerations.


Function argument evaluation considerations

It is important to remember that ColdFusion always evaluates function arguments before the argument values are passed to a function:

For example, consider the following DE function:

<cfoutput>#DE("1" & "2")#</cfoutput>

You might expect this line to display """1"" & ""2""". Instead, it displays "12", because ColdFusion processes the line as follows:

  1. Evaluates the expression "1" & "2" as the string "12".
  2. Passes the string "12" (without the quotes) to the DE function.
  3. Calls the DE function, which adds literal quotation marks around the 12.

Similarly, if you use the expression DE(1 + 2), ColdFusion evaluates 1 + 2 as the integer 3 and passes it to the function. The function converts it to a string and surrounds the string in literal quotation marks, giving "3".


About the Evaluate function

The following example can help you understand the Evaluate function and how it works with ColdFusion variable processing:

<cfset myVar2="myVar">
<cfset myVar="27/9">
<cfoutput>
   #myVar2#<br>
   #myVar#<br>
   #Evaluate("myVar2")#<br>
   #Evaluate("myVar")#<br>
   #Evaluate(myVar2)#<br>
   #Evaluate(myVar)#<br>
</cfoutput>

The following table describes how ColdFusion processes this code:

Code
Description
<cfset myVar2="myVar">
<cfset myVar="27/9">
Sets the two variables to the following strings:
myVar
27/9
<cfoutput>
   #myVar2#<br>
   #myVar#<br>
Displays the values assigned to the variables, myVar and 27/9 respectively.
   #Evaluate("myVar2")#<br>
Passes the string "myvar2" (without the quotes) to the Evaluate function, which does the following:
  1. Evaluates it as the variable myVar2.
  2. Returns the value of the myVar2 variable, the string "myvar" (without the quotes).
   #Evaluate("myVar")#<br>
Passes the string "myvar" (without the quotes) to the Evaluate function, which does the following:
  1. Evaluates it as the variable myVar.
  2. Returns the value of the myVar variable, the string "27/9" (without the quotes).
   #Evaluate(myVar2)#<br>
Evaluates the variable myVar2 as the string "myVar" and passes the string (without the quotes) to the Evaluate function. The rest of the processing is the same as in the previous line.
   #Evaluate(myVar)#<br>
</cfoutput>
Evaluates the variable myVar as the string "27/9" (without the quotes), and passes it to the Evaluate function, which does the following:
  1. Evaluates the string as the expression 27/9
  2. Performs the division.
  3. Returns the resulting value, 3.

As you can see, using dynamic expressions can result in substantial expression evaluation overhead, and the code can be confusing. Therefore, you should avoid using dynamic expressions wherever a simpler technique, such as using indexed arrays or structures can serve your purposes.


Avoiding the Evaluate function

Using Evaluate function increases processing overhead, and in most cases you do not need to use it. The following sections provide examples of cases where you might consider using the Evaluate function, but it is not necessary.


Example 1

You might be inclined to use the Evaluate function in code such as the following:

<cfoutput>1 + 1 is #Evaluate(1 + 1)#</cfoutput>

Although this code works, it is not as efficient as the following code:

<cfset Result = 1 + 1>
<cfoutput>1 + 1 is #Result#</cfoutput>


Example 2

This example shows how you can use an associative array reference in place of an Evaluate function. This technique is powerful because:

  • Most ColdFusion scopes are accessible as structures.
  • You can use ColdFusion expressions in the indexes of associative array structure references. (For more information on using associative array references for structures, see Structure notation.)

The following example uses the Evaluate function to construct a variable name:

<cfoutput>
Product Name: #Evaluate("Form.product_#i#")#
</cfoutput>

This code comes from an example where a form has entries for an indeterminate number of items in a shopping cart. For each item in the shopping cart there is a product name field. The field name is of the form product_1, product_2, and so on, where the number corresponds to the product’s entry in the shopping cart. In this example, ColdFusion does the following:

  1. Replaces the variable i with its value, for example 1.
  2. concatenates the variable value with "Form.product_", and passes the result (for Form.product_1) to the Evaluate function, which does the remaining steps.
  3. Parses the variable product_1 and generates an executable representation of the variable. Because ColdFusion must invoke its parser, this step requires substantial processing, even for a simple variable.
  4. Evaluates the representation of the variable, for example as "Air popper".
  5. Returns the value of the variable.

The following example has the same result as the preceding example and is more efficient:

<cfoutput>
ProductName: #Form["product_" & i]#
</cfoutput>

In this code, ColdFusion does the following:

  1. Evaluates the expression in the associative array index brackets as the string "product_" concatenated with the value of the variable i.
  2. Determines the value of the variable i; 1
  3. Concatenates the string and the variable value to get product_1
  4. Uses the result as the key value in the Form structure to get Form[product_1]. This associative array reference accesses the same value as the object.attribute format reference Form.product_1; in this case, Air popper.

This code format does not use any dynamic evaluation, but it achieves the same effect, of dynamically creating a structure reference by using a string and a variable.


SetVariable function considerations

You can avoid using the SetVariable function by using a format such as the following to set a dynamically named variable. For example, the following lines are equivalent:

<cfset SetVariable("myVar" & i, myVal)>

<cfset "myVar#i#" = myVal>

In the second line, enclosing the myVar#i# variable name in quotes tells ColdFusion to evaluate the name and process any text in pound signs as a variable or function. ColdFusion replaces the #i# with the value of the variable i, so that if the value of i is 12, this code is equivalent to the line

<cfset myVar12 = myVal>

For more information on this usage, see Using pound signs to construct a variable name in assignments.


Using the IIF function

The IIF function is a shorthand for the following code:

<cfif argument1>
   <cfset result = Evaluate(argument1)>
<cfelse>
   <cfset result = Evaluate(argument2)>
</cfif>

The function returns the value of the result variable. It is comparable to the use of the JavaScript and Java ? : operator, and can result in more compact code. As a result, the IIF function can be convenient even if you are not using dynamic expressions.

The IIF function requires the DE function to prevent ColdFusion from evaluating literal strings, as the following example shows:

<cfoutput>
#IIf(IsDefined("LocalVar"), "LocalVar", DE("The variable is not
defined."))#
</cfoutput>

If you do not enclose the string "The variable is not defined." in a DE function, the IIF function tries to evaluate the contents of the string as an expression and generates an error (in this case, an invalid parser construct error).

The IIF function is useful for incorporating ColdFusion logic in-line in HTML code, but it entails a processing time penalty in cases where you do not otherwise need dynamic expression evaluation.

The following example shows using IIF to alternate table row background color between white and gray. It also shows the use of the DE function to prevent ColdFusion from evaluating the color strings.

<cfoutput>
<table border="1" cellpadding="3">
<cfloop index="i" from="1" to="10">
   <tr bgcolor="#IIF( i mod 2 eq 0, DE("white"), DE("gray") )#">
      <td>
         hello #i#
      </td>
   </tr>
</cfloop>
</table>
</cfoutput>

This code is more compact than the following example which does not use IIF or DE.

<cfoutput>
<table border="1" cellpadding="3">
<cfloop index="i" from="1" to="10">
   <cfif i mod 2 EQ 0>
      <cfset Color = "white">
   <cfelse>
      <cfset Color = "gray">
   </cfif>
   <tr bgcolor="#color#">
      <td>
         hello #i#
      </td>
   </tr>
</cfloop>
</table>
</cfoutput>


Example: a dynamic shopping cart

The following example dynamically creates and manipulates variable names without using dynamic expression evaluation by using associative array notation.

You need to dynamically generate variable names in applications such as shopping carts, where the required output is dynamically generated and variable. In a shopping cart, you do not know in advance the number of cart entries or their contents. Also, because you are using a form, the action page only receives Form variables with the names and values of the form fields.

The following example shows the shopping cart contents and lets you edit your order and submit it. To simplify things, the example automatically generates the shopping cart contents using CFScript instead of having the user fill the cart. A more complete example would populate a shopping cart as the user selected items. Similarly, the example omits all business logic for committing and making the order.


To create the form

  1. Create a new file in your editor.
    2. <html>
<head>
   <title>Shopping Cart</title>
</head>
<cfscript>
CartItems=4;
Cart = ArrayNew(1);
for ( i=1; i LE cartItems; i=i+1)
{
   Cart[i]=StructNew();
   Cart[i].ID=i;
   Cart[i].Name="Product " & i;
   Cart[i].SKU=i*100+(2*i*10)+(3*i);
   Cart[i].Qty=3*i-2;
}
</cfscript>

<body>
Your shopping cart has the following items.<br>
You can change your order quantities.<br>
If you don't want any item, clear the item's check box.<br>
When you are ready to order, click submit.<br>
<br>
<cfform name="ShoppingCart" action="ShoppingCartAction.cfm" method="post">
  <table>
   <tr>
     <td>Order?</td>
     <td>Product</td>
     <td>Code</td>
     <td>Quantity</td>
   </tr>
   <cfloop index="i" from="1" to="#cartItems#">
      <tr>
        <cfset productName= "product_" & Cart[i].ID>
        <cfset skuName= "sku_" & Cart[i].ID>
        <cfset qtyname= "qty_" & Cart[i].ID>
        <td><cfinput type="checkbox" name="itemID" value="#Cart[i].ID#" checked>
          </td>
        <td><cfinput type="text" name="#productName#" value="#Cart[i].Name#"
          passThrough = "readonly = 'True'"></td>
        <td><cfinput type="text" name="#skuName#" value="#Cart[i].SKU#"
          passThrough = "readonly = 'True'"></td>
        <td><cfinput type="text" name="#qtyName#" value="#Cart[i].Qty#">
          </td>
      </tr>
   </cfloop>
  </table>
  <input type="submit" name="submit" value="submit">
</cfform>

</body>
</html>
  2. Save the page as ShoppingCartForm.cfm.


Reviewing the code

The following table describes the code:

Code
Description
<cfscript>
CartItems=4;
Cart = ArrayNew(1);
for ( i=1; i LE #cartItems#; i=i+1)
{
   Cart[i]=StructNew();
   Cart[i].ID=i;
   Cart[i].Name="Product " & i;
   Cart[i].SKU=i*100+(2*i*10)+(3*i);
   Cart[i].Qty=3*i-2;
}
</cfscript>
Create a shopping cart as an array of structures, with each structure containing the cart item ID, product name, SKU number, and quantity ordered for one item in the cart. Populate the shopping cart by looping CartItems times and setting the structure variables to arbitrary values based on the loop counter. A real application would set the Name, SKU, and Quantity values on other pages.
<cfform name="ShoppingCart"
      action="ShoppingCartAction.cfm"
      method="post">
  <table>
      <tr>
         <td>Order?</td>
         <td>Product</td>
         <td>Code</td>
         <td>Quantity</td>
      </tr>
Start the form and its embedded table. When the user clicks the submit button, post the form data to the ShoppingCartAction.cfm page.
The table formats the form neatly. The first table row contains the column headers. Each following row has the data for one cart item.
   <cfloop index="i" from="1" to="#cartItems#">
      <tr>
         <cfset productName= "product_" &
            Cart[i].ID>
         <cfset skuName= "sku_" & Cart[i].ID>
         <cfset qtyname= "qty_" & Cart[i].ID>
         <td><cfinput type="checkbox"
            name="itemID" value="#Cart[i].ID#"
            checked>
         </td>
         <td><cfinput type="text"
            name="#productName#"
            value="#Cart[i].Name#"
            passThrough = "readonly = 'True'">
         </td>
         <td><cfinput type="text"
            name="#skuName#"
            value="#Cart[i].SKU#"
            passThrough = "readonly = 'True'">
         </td>
        <td><cfinput type="text"
            name="#qtyName#"
            value="#Cart[i].Qty#">
         </td>
      </tr>
   </cfloop>
  </table>
Loop through the shopping cart entries to generate the cart form dynamically. For each loop, generate variables used for the form field name attributes by appending the cart item ID (Cart[i].ID) to a field type identifier, such as "sku_".
Use a single name, "itemID", for all check boxes. This way, the itemID value posted to the action page is a list of all the check box field values. The check box field value for each item is the cart item ID.
Each column in a row contains a field for a cart item structure entry. The passthrough attribute sets the product name and SKU fields to read-only; note the use of single quotes. (For more information on the cfinput tag passthrough attribute, see the CFML Reference.) The check boxes are selected by default.
<input type="submit" name="submit"
   value="Submit">
</form>
Create the Submit button and end the form.


To Create the Action page

  1. Create a new file in your editor.
  2. Enter the following text:
    3. <html>
<head>
   <title>Your Order</title>
</head>
<body>
<cfif isDefined("Form.submit")>
   <cfparam name="Form.itemID" default="">
   <cfoutput>
      You have ordered the following items:<br>
      <br>
      <cfloop index="i" list="#Form.itemID#">
         ProductName: #Form["product_" & i]#<br>
         Product Code: #Form["sku_" & i]#<br>
         Quantitiy: #Form["qty_" & i]#<br>
         <br>
      </cfloop>
   </cfoutput>
</cfif>
</body>
</html>
  3. Save the file as ShoppingCartAction.cfm
  4. Open ShoppingCartform.cfm in your browser, change the check box and quantity values, and click Submit.


Reviewing the code

The following table describes the code:

Code
Description
<cfif isDefined("Form.submit")>
Run the CFML on this page only if it is called by submitting a form. This is not needed if there are separate form and action pages, but is required if the form and action page were one CFML page.
<cfparam name="Form.itemID"
   default="">
Set the default Form.itemID to the empty string. This prevents ColdFusion from displaying an error if the user clears all check boxes before submitting the form (so no product IDs are submitted).
<cfoutput>
You haver ordered the following
      items:<br>
<br>
<cfloop index="i" list=
      "#Form.itemID#">
   ProductName:
      #Form["product_" & i]#<br>
   Product Code:
      #Form["sku_" & i]#<br>
   Quantitiy:
      #Form["qty_" & i]#<br>
   <br>
</cfloop>
</cfoutput>
</cfif>
Display the name, SKU number, and quantity for each ordered item.
The form page posts Form.itemID as a list containing the value attributes of all the check boxes. These attributes contain the shopping cart item IDs for the selected cart items. Use the list values to index a loop that outputs each ordered item.
Use associative array notation to access the Form scope as a structure and use expressions in the array indexes to construct the form variable names. The expressions consist of a string containing the field name’s field type prefix (for example, "sku_"), concatenated with the variable i, which contains the shopping cart ItemID number (which is also the loop index variable).

Previous


Using Arrays and Structures

ColdFusion supports dynamic multidimensional arrays. This chapter explains the basics of creating and handling arrays. It also provides several examples showing how arrays can enhance your ColdFusion application code.

ColdFusion also supports structures for managing lists of key-value pairs. Because structures can contain other structures or complex data types as it values, they provide a flexible and powerful tool for managing complex data. This chapter explains the basics of creating and working with structures.

Contents
  • About Arrays
  • Basic Array Techniques
  • Populating Arrays with Data
  • Array Functions
  • About Structures
  • Creating and Using Structures
  • Structure Example
  • Structure Functions
Next


About Arrays

Traditionally, an array is a tabular structure used to hold data, much like a spreadsheet table with clearly defined limits and dimensions.

In ColdFusion, you typically use arrays to temporarily store data. For example, if your site allows users to order goods online, you can store their shopping cart contents in an array. This allows you to make changes easily without committing the information, which the user can change before completing the transaction, to a database.


Basic Array Concepts

The following terms will help you understand subsequent discussions of ColdFusion arrays:

  • Array dimension The relative complexity of the array structure.
  • Index The position of an element in a dimension, ordinarily surrounded by square brackets: my1Darray[1], my2Darray[1][1], my3Darray[1][1][1].
  • Array element Data stored at an array index.

The simplest array is a one-dimensional array, similar row in a table. A one-dimensional array has a name (the variable name) and a numerical index. The index number references a single entry, or cell, in the array, as the following figure shows:

This is a picture of the feature being described.

Thus, the following statement sets the value of the fifth entry in the one-dimensional array MyArray to "Robert":

<cfset MyArray[5] = "Robert">

A basic two-dimensional (2D) array is like a simple table. A three-dimensional array is like a cube of data, and so on. ColdFusion lets you directly create arrays with up to three dimensions. You can use multiple statements to create arrays with more than three dimensions.

The syntax my2darray[1][3]="Paul" is the same as saying 'My2dArray is a two-dimensional array and the value of the array element index [1][3] is "Paul"'.


About ColdFusion Arrays

ColdFusion arrays differ from traditional arrays, because they are dynamic. For example, in a conventional array, array size is constant and symmetrical, whereas in a ColdFusion array, you can have rows of differing lengths based on the data that has been added or removed.

The following figures show the differences between traditional arrays and ColdFusion arrays using 2D arrays. The differences between traditional and ColdFusion 3D arrays are similar, but a lot harder to show on a page.

A conventional 2D array is like a fixed-size table made up of individual cells, as the following figure shows:

This is a picture of the feature being described.

The following figure represents a ColdFusion 2D array:

This is a picture of the feature being described.

A ColdFusion 2D array is actually a one-dimensional array that contains a series of additional 1D arrays. Each of the arrays that make up a row can expand and contract independently of any other column. Similarly, a ColdFusion 3D array is essentially three nested sets of 1D arrays.

Dynamic arrays expand to accept data you add to them and contract as you remove data from them.


Basic Array Techniques

The following sections describe how to reference array elements, create arrays, add and remove array elements, and copy arrays.


Referencing array elements

You reference array elements by enclosing the index with brackets: arrayName[x] where x is the index that you want to reference. In ColdFusion, array indexes are counted starting with position 1, which means that position 1 in the firstname array is referenced as firstname[1]. For 2D arrays, you reference an index by specifying two coordinates: myarray[1][1].

You can use ColdFusion variables and expressions inside the square brackets to reference an index, as the following example shows:

<cfset myArray=ArrayNew(1)>
<cfset myArray[1]="First Array Element">
<cfset myArray[1 + 1]="Second Array" & "Element">
<cfset arrayIndex=3>
<cfset arrayElement="Third Array Element">
<cfset myArray[arrayIndex]=arrayElement>
<cfset myArray[arrayIndex + 1]="Fourth Array Element">
<cfdump var=#myArray#>

Note: The IsDefined function does not test the existence of array elements. To test whether data exists at an array index, copy the array element to a simple variable and use the IsDefined function to test the existence of the copy.


Creating arrays

In ColdFusion, you declare an array by assigning a variable name to the new array and specifying its dimensions, as follows:

<cfset mynewarray=ArrayNew(x)>

where x is the number of dimensions (from 1 to 256) in the array that you want to create.

Once you declare an array, you can add array elements, which you can then reference using the elements’ indexes.

For example, suppose you declare a 1D array called "firstname":

<cfset firstname=ArrayNew(1)>

The array firstname holds no data and is of an unspecified length. Next you add data to the array:

<cfset firstname[1]="Coleman">
<cfset firstname[2]="Charlie">
<cfset firstname[3]="Dexter">

After you add these names to the array, it has a length of 3.


Creating complex multidimensional arrays

ColdFusion supports dynamic multidimensional arrays. When you declare an array with the ArrayNew function, you specify the number of dimensions. You can create an asymmetrical array or increase an existing array's dimensions by nesting arrays as array elements.

It is important to note that when you assign one array (array1) to an element of another array (array2), array1 is copied into array2. The original copy of array1 still exists, independent of array2. You can then change the contents of the two arrays independently.

The best way to understand an asymmetrical array is by looking at it. The following example creates an asymmetric, multidimensional array and the cfdump tag displays the resulting array structure. Note that several array elements do not yet contain data.

<cfset myarray=ArrayNew(1)>
<cfset myotherarray=ArrayNew(2)>
<cfset biggerarray=ArrayNew(3)>

<cfset biggerarray[1][1][1]=myarray>
<cfset biggerarray[1][1][1][10]=3>
<cfset biggerarray[2][1][1]=myotherarray>
<cfset biggerarray[2][1][1][4][2]="five deep">

<cfset biggestarray=ArrayNew(3)>
<cfset biggestarray[3][1][1]=biggerarray>
<cfset biggestarray[3][1][1][2][3][1]="This is complex">
<cfset myarray[3]="Can you see me">

<cfdump var=#biggestarray#><br>
<cfdump var=#myarray#>

Note: The cfdump tag displays the entire contents of an array. It is an excellent tool for debugging arrays and array-handling code.


Reviewing the code

The following table describes the code:

Code
Description
<cfset myarray=ArrayNew(1)>
<cfset myotherarray=ArrayNew(2)>
<cfset biggerarray=ArrayNew(3)>
Create three empty arrays, a 1D array, a 2D array, and a 3D array.
<cfset biggerarray[1][1][1]=myarray>
<cfset biggerarray[1][1][1][10]=3>
Make element [1][1][1] of the 3D bigerarray array be a copy of the 1D array. Assign 3 to the [1][1][1][10] element of the resulting array.
The bigerarray array is now asymmetric. For example, it does not have a [1][1][2][1] element.
<cfset biggerarray[2][1][1]=
   myotherarray>
<cfset biggerarray[2][1][1][4][2]=
   "reality">
Make element [2][1][1] of the 3D array be the 2D array and assign the [2][1][1][4][2] element the value "reality".
The bigerarray array is now even more asymmetric.
<cfset biggestarray=ArrayNew(3)>
<cfset biggestarray[3][1][1]
   =biggerarray>
<cfset biggestarray[3][1][1][2][3][1]
   ="This is complex">
Create a second 3D array. Make the [3][1][1] element of this array be a copy of the bigerarray array, and assign element [3][1][1][2][3][1].
The resulting array is very complex and asymmetric.
<cfset myarray[3]="Can you see me">
Assign a value to element [3] of myarray.
<fdump var=#biggestarray#><br>
<cfdump var=#myarray#>
Use cfdump to view the structure of biggestarray and myarray.
Notice that the "Can you see me" entry appears in myarray, but not in biggestarray, because biggestarray has a copy of the original myarray values and is not affected by the change to myarray.


Adding elements to an array

You can add an element to an array by assigning the element a value or by using a ColdFusion function.


Adding an array element by assignment

You can add elements to an array by defining the value of an array element, as shown in the following cfset tag:

<cfset myarray[5]="Test Message">

If an element does not exist at the specified index, ColdFusion creates it. If an element already exists at the specified index, ColdFusion replaces it with the new value. To prevent existing data from being overwritten, use the ArrayInsertAt function, as described in the next section.

If elements with lower-number indexes do not exist, they remain undefined. You must assign values to undefined array elements before you can use them. For example, the following code creates an array and an element at index 4. It outputs the contents of element 4, but generates an error when it tries to output the (nonexistent) element 3.

<cfset myarray=ArrayNew(1)>
<cfset myarray[4]=4>
<cfoutput>
   myarray4: #myarray[4]#<br>
   myarray3: #myarray[3]#<br>
</cfoutput>


Adding an array element with a function

You can use the following array functions to add data to an array:

Function | Description
ArrayAppend | Creates a new array element at the end of the array.
ArrayPrepend | Creates a new array element at the beginning of the array.
ArrayInsertAt | Inserts an array element at the specified index position.

Because ColdFusion arrays are dynamic, if you add or delete an element from the array, any higher-numbered index values all change. For example, the following code creates a two element array and displays the array contents. It then uses ArrayPrepend to insert a new element at the beginning of the array and displays the result. The data that was originally in indexes 1 and 2 is now in indexes 2 and 3.

<!--- Create an array with three elelemts --->
<cfset myarray=ArrayNew(1)>
<cfset myarray[1]="Original First Element">
<cfset myarray[2]="Original Second Element">
<!--- Use cfdump to display the array structure --->
<cfdump var=#myarray#>
<br>
<!--- Add a new element at the beginning of the array --->
<cfscript>
   ArrayPrepend(myarray, "New First Element");
</cfscript>
<!--- Use cfdump to display the new array structure --->
<cfdump var=#myarray#>

For more information about these array functions, see the CFML Reference.


Deleting elements from an array

Use the ArrayDeleteAt function to delete data from the array at a particular index, instead of setting the data value to zero or an empty string. If you remove data from an array, the array resizes dynamically, as the following example shows:

<!--- Create an array with three elements --->
<cfset firstname=ArrayNew(1)>
<cfset firstname[1]="Robert">
<cfset firstname[2]="Wanda">
<cfset firstname[3]="Jane">
<!--- Delete the second element from the array --->
<cfset temp=ArrayDeleteAt(firstname, 2)>
<!--- Display the array length (2) and its two entries,
which are now "Robert" and "Jane" --->
<cfoutput>
   The array now has #ArrayLen(firstname)# indexes<br>
   The first entry is #firstname[1]#<br>
   The second entry is #firstname[2]#<br>
</cfoutput>

The ArrayDeleteAt function removed the original second element and resized the array so that it has two entries, with the second element now being the original third element.


Copying arrays

You can copy arrays of simple variables (numbers, strings, Boolean values, and date-time values) by assigning the original array to a new variable name. You do not have to use ArrayNew to create the new array first. When you assign the existing array to a new variable, ColdFusion creates a new array and copies the old array’s contents to the new array. The following example creates and populates a two-element array. It then copies the original array, changes one element of the copied array and dumps both arrays. As you can see, the original array is unchanged and the copy has a new second element.

<cfset myArray=ArrayNew(1)>
<cfset myArray[1]="First Array Element">
<cfset myArray[2]="Second Array Element">
<cfset newArray=myArray>
<cfset newArray[2]="New Array Element 2">
<cfdump var=#myArray#><br>
<cfdump var=#newArray#>

If your array contains complex variables (structures, query objects, or external objects such as COM objects) assigning the original array to a new variable does not make a complete copy of the original array. The array structure is copied; however, the new array does not get its own copy of the complex data, only references to it. To illustrate this behavior, run the following code:

Create an array that contains a structure.<br>
<cfset myStruct=StructNew()>
<cfset myStruct.key1="Structure key 1">
<cfset myStruct.key2="Structure key 2">
<cfset myArray=ArrayNew(1)>
<cfset myArray[1]=myStruct>
<cfset myArray[2]="Second array element">
<cfdump var=#myArray#><br>
<br>
Copy the array and dump it.<br>
<cfset myNewArray=myArray>
<cfdump var=#myNewArray#><br>
<br>
Change the values in the new array.<br>
<cfset myNewArray[1].key1="New first array element">
<cfset myNewArray[2]="New second array element">
<br>
Contents of the original array after the changes:<br>
<cfdump var=#myArray#><br>
Contents of the new array after the changes:<br>
<cfdump var=#myNewArray#>

The change to the new array also changes the contents of the structure in the original array.

To make a complete copy of an array that contains complex variables, use the duplicate function.


Populating Arrays with Data

Array elements can store any values, including queries, structures, and other arrays. You can use a number of functions to populate an array with data, including ArraySet, ArrayAppend, ArrayInsertAt, and ArrayPrepend. These functions are useful for adding data to an existing array.

In particular, you should master the following basic techniques:

  • Populating an array with the ArraySet function
  • Populating an array with the cfloop tag
  • Populating an array from a query

The following sections describe these techniques.


Populating an array with the ArraySet function

You can use the ArraySet function to populate a 1D array, or one dimension of a multidimensional array, with some initial value, such as an empty string or zero. This can be useful if you need to create an array of a certain size, but do not need to add data to it right away. One reason to do this is so that you can refer to all the array indexes. If you refer to an array index that does not contain some value, such as an empty string, you get an error.

The ArraySet function has the following form:

ArraySet (arrayname, startrow, endrow, value)

The following example initializes the array myarray, indexes 1 to 100, with an empty string:

ArraySet (myarray, 1, 100, "")


Populating an array with the cfloop tag

The cfloop tag provides a common and very efficient method for populating an array. The following example uses a cfloop tag and the MonthAsString function to populate a simple 1D array with the names of the months. A second cfloop outputs data in the array to the browser.

<cfset months=arraynew(1)>

<cfloop index="loopcount" from=1 to=12>
   <cfset months[loopcount]=MonthAsString(loopcount)>
</cfloop>

<cfloop index="loopcount" from=1 to=12>
      <cfoutput>
         #months[loopcount]#<br>
      </cfoutput>
</cfloop>


Using nested loops for 2D and 3D arrays

To output values from 2D and 3D arrays, you must employ nested loops to return array data. With a 1D array, a single cfloop is sufficient to output data, as in the previous example. With arrays of dimension greater than one, you need to maintain separate loop counters for each array level.


Nesting cfloop tags for a 2D array

The following example shows how to handle nested cfloop tags to output data from a 2D array. It also uses nested cfloop tags to populate the array:

<cfset my2darray=arraynew(2)>
<cfloop index="loopcount" from=1 to=12>
   <cfloop index="loopcount2" from=1 to=2>
      <cfset my2darray[loopcount][loopcount2]=(loopcount * loopcount2)>
   </cfloop>
</cfloop>

<p>The values in my2darray are currently:</p>

<cfloop index="OuterCounter" from="1" to="#ArrayLen(my2darray)#">
   <cfloop index="InnerCounter" from="1"
         to="#ArrayLen(my2darray[OuterCounter])#">
      <cfoutput>
         <b>[#OuterCounter#][#InnerCounter#]</b>:
         #my2darray[OuterCounter][InnerCounter]#<br>
      </cfoutput>
   </cfloop>
</cfloop>


Nesting cfloop tags for a 3D array

For 3D arrays, you simply nest an additional cfloop tag. (This example does not set the array values first to keep the code short.)

<cfloop index="Dim1" from="1" to="#ArrayLen(my3darray)#">
   <cfloop index="Dim2" from="1" to="#ArrayLen(my3darray[Dim1])#">
      <cfloop index="Dim3" from="1"
            to="#ArrayLen(my3darray[Dim1][Dim2])#">
         <cfoutput>
            <b>[#Dim1#][#Dim2#][#Dim3#]</b>:
            #my3darray[Dim1][Dim2][Dim3]#<br>
         </cfoutput>
      </cfloop>
   </cfloop>
</cfloop>


Populating an array from a query

When populating an array from a query, keep the following things in mind:

  • You cannot add query data to an array all at once. A looping structure is generally required to populate an array from a query.
  • You can reference query column data using array-like syntax. For example, myquery.col_name[1] references data in the first row in the col_name column of the myquery query.
  • Inside a cfloop query= loop, you do not have to specify the query name to reference the query’s variables.

You can use a cfset tag with the following syntax to define values for array indexes:

<cfset arrayName[index]=queryColumn[row]>

In the following example, a cfloop tag places four columns of data from a sample data source into an array, "myarray".

<!--- Do the query --->
<cfquery name="test" datasource="cfsnippets">
   SELECT Emp_ID, LastName, FirstName, Email
   FROM Employees
</cfquery>

<!--- Declare the array --->
<cfset myarray=arraynew(2)>

<!--- Populate the array row by row --->
<cfloop query="test">
   <cfset myarray[CurrentRow][1]=Emp_ID>
   <cfset myarray[CurrentRow][2]=LastName>
   <cfset myarray[CurrentRow][3]=FirstName>
   <cfset myarray[CurrentRow][4]=Email>
</cfloop>

<!--- Now, create a loop to output the array contents --->
<cfset total_records=test.recordcount>
<cfloop index="Counter" from=1 to="#Total_Records#">
   <cfoutput>
      ID: #MyArray[Counter][1]#,
      LASTNAME: #MyArray[Counter][2]#,
      FIRSTNAME: #MyArray[Counter][3]#,
      EMAIL: #MyArray[Counter][4]# <br>
   </cfoutput>
</cfloop>

Note that this example uses the query object built-in variable CurrentRow to index the first dimension of the array.


Array Functions

The following functions are available for creating, editing, and handling arrays:

Function
Description
ArrayAppend
Appends an array element to the end of a specified array.
ArrayAvg
Returns the average of the values in the specified array.
ArrayClear
Deletes all data in a specified array.
ArrayDeleteAt
Deletes an element from a specified array at the specified index and resizes the array.
ArrayInsertAt
Inserts an element (with data) in a specified array at the specified index and resizes the array.
ArrayIsEmpty
Returns TRUE if the specified array is empty of data.
ArrayLen
Returns the length of the specified array.
ArrayMax
Returns the largest numeric value in the specified array.
ArrayMin
Returns the smallest numeric value in the specified array.
ArrayNew
Creates a new array of specified dimension.
ArrayPrepend
Adds an array element to the beginning of the specified array.
ArrayResize
Resets an array to a specified minimum number of elements.
ArraySet
Sets the elements in a 1D array in a specified range to a specified value.
ArraySort
Returns the specified array with elements sorted numerically or alphanumerically.
ArraySum
Returns the sum of values in the specified array.
ArraySwap
Swaps array values in the specified indexes.
ArrayToList
Converts the specified one-dimensional array to a list, delimited with the character you specify.
IsArray
Returns True if the value is an array.
ListToArray
Converts the specified list, delimited with the character you specify, to an array.

For more information about each of these functions, see the CFML Reference.


About Structures

ColdFusion structures consist of key-value pairs. Structures let you build a collection of related variables that are grouped under a single name. You can define ColdFusion structures dynamically.

You can use structures to refer to related values as a unit, rather than individually. To maintain employee lists, for example, you can create a structure that holds personnel information such as name, address, phone number, ID numbers, and so on. Then you can refer to this collection of information as a structure called employee rather than as a collection of individual variables.

A structure's key must be a string. The values associated with the key can be any valid ColdFusion value or object. It can be a string or integer, or a complex object such as an array or another structure. Because structures can contain any kind of data they provide a very powerful and flexible mechanism for representing complex data.


Structure notation

ColdFusion supports two types of notation for referencing structure contents. Which notation you use depends on your needs:

Notation
Description
Object.property
You can refer to a property, prop, of an object, obj, as obj.prop. This notation is useful for simple assignments, as in this example:
depts.John="Sales"
Use this notation only when you know the property names (keys) in advance and they are strings, with no special characters, numbers, or spaces. You cannot use the dot notation when the property, or key, is dynamic.
Associative arrays
If you do not know the key name is in advance, or it contains spaces, numbers or special characters, you can use associative array notation. This notation uses structures as arrays with string indexes, for example,
depts["John"]="Sales"
depts[employeeName]="Sales"
You can use a variable (such as employeeName) as an associative array index. Therefore, you must enclose any literal key names in quotes. For information on using associative array references containing variables, see Dynamically constructing structure references.


Referencing complex structures

When a structure contains another structure, you reference the data in the nested structure by extending either object.property or associative array notation. You can even use a mixture of both notations.

For example, if structure1 has a key key1 whose value is a structure that has keys struct2key1, struct2key2, and so on, you can use any of the following references to access the data in the first key of the embedded structure:

Structure1.key1.Struct2key1
Structure1["key1"].Struct2key1
Structure1.key1["Struct2key1"]
Structure1["key1"]["Struct2key1"]

The following example shows various ways you can reference the contents of a complex structure:

<cfset myArray=ArrayNew(1)>
<cfset myArray[1]="2">
<cfset myArray[2]="3">
<cfset myStruct2=StructNew()>
<cfset myStruct2.struct2key1="4">
<cfset myStruct2.struct2key2="5">
<cfset myStruct=StructNew()>
<cfset myStruct.key1="1">
<cfset myStruct.key2=myArray>
<cfset myStruct.key3=myStruct2>
<cfdump var=#myStruct#><br>

<cfset key1Var="key1">
<cfset key2Var="key2">
<cfset key3Var="key3">
<cfset var2="2">

<cfoutput>
Value of the first key<br>
#mystruct.key1#<br>
#mystruct["key1"]#<br>
#mystruct[key1Var]#<br>
<br>
Value of the second entry in the key2 array<br>
#myStruct.key2[2]#<br>
#myStruct["key2"][2]#<br>
#myStruct[key2Var][2]#<br>
#myStruct[key2Var][var2]#<br>
<br>
Value of the struct2key2 entry in the key3 structure<br>
#myStruct.key3.struct2key2#<br>
#myStruct["key3"]["struct2key2"]#<br>
#myStruct[key3Var]["struct2key2"]#<br>
#myStruct.key3["struct2key2"]#<br>
#myStruct["key3"].struct2key2#<br>
<br>
</cfoutput>


Reviewing the code

The following table describes the code:

Code
Description
<cfset myArray=ArrayNew(1)>
<cfset myArray[1]="2">
<cfset myArray[2]="3">
<cfset myStruct2=StructNew()>
<cfset myStruct2.struct2key1="4">
<cfset myStruct2.struct2key2="5">
<cfset myStruct=StructNew()>
<cfset myStruct.key1="1">
<cfset myStruct.key2=myArray>
<cfset myStruct.key3=myStruct2>
Create a structure with three entries: a string, an array, and an embedded structure.
<cfdump var=#myStruct#><br>
Display the complete structure.
<cfset key1Var="key1">
<cfset key2Var="key2">
<cfset key3Var="key3">
<cfset var2="2">
Create variables containing the names of the myStruct keys and the number 2.
<cfoutput>
Value of the first key<br>
#mystruct.key1#<br>
#mystruct["key1"]#<br>
#mystruct[key1Var]#<br>
<br>
Output the value of the structure’s key1 (string) entry using:
  • object.property notation
  • associative array notation with a constant
  • associative array notation with a variable
Value of the second entry in the
key2 array<br>
#myStruct.key2[2]#<br>
#myStruct["key2"][2]#<br>
#myStruct[key2Var][2]#<br>
#myStruct[key2Var][var2]#<br>
<br>
Output the value of the second entry in the structure’s key2 array using:
  • object.property notation
  • associative array notation with a constant
  • associative array notation with a variable
  • associative array notation with variables for both the array and the array index.
Value of the struct2key2 entry in
the key3 structure<br>
#myStruct.key3.struct2key2#<br>
#myStruct["key3"]["struct2key2"]#<br>
#myStruct[key3Var]["struct2key2"]#<br>
#myStruct.key3["struct2key2"]#<br>
#myStruct["key3"].struct2key2#<br>
<br>
</cfoutput>
Output the value of second entry in the structure’s key3 embedded structure using:
  • object.property notation
  • associative array notation with two constants
  • associative array notation with a variable and a constant
  • object.property notation followed by associative array notation
  • associative array notation followed by object.property notation.


Creating and Using Structures

This section explains how to create and use structures in ColdFusion. The sample code in this section uses a structure called employee, which is used to add new employees to a corporate information system.


Creating structures

You can create a structure by creating a first key-pair or by using the ColdFusion StructNew function.


Creating structures by assigning values

You can create a structure by assigning a key-value pair. For example, the following line creates a structure named myStruct with one element, name, that has the value Macromedia.

<cfset myStruct.name="Macromedia">


Creating structures using a function

You can create structures by assigning a variable name to the structure with the StructNew function as follows:

<cfset mystructure=StructNew()>

For example, to create a structure named departments, use the following syntax:

<cfset departments=StructNew()>

This creates an empty structure to which you can add data.

Use this technique to create structures if your application must run on ColdFusion Server versions 5 and earlier.


Adding data elements to structures

You add an element to a structure by assigning the element a value or by using a ColdFusion function. It is cleaner and more efficient to use direct assignment, so only this technique is described.

You add structure key-value pairs by defining the value of the structure key, as shown in the following example:

<cfset myNewStructure.key1="A new structure with a new key">
<cfdump var=#myNewStructure#>
<cfset myNewStructure.key2="Now I’ve added a second key">
<cfdump var=#myNewStructure#>


Updating values in structures

You can update structure element values by assignment or by using the StructUpdate function. Direct assignment results in simpler code than using a function, so only the assignment technique is described.

To update a structure value, assign the key a new value. For example, the following code uses cfset and object.property notation to create a new structure element called departments.John and change John’s department from Sales to Marketing. It then uses associative array notation to change his department to Facilities. Each time the department changes, it displays the results:

<cfset departments=structnew()>
<cfset departments.John = "Sales">
<cfoutput>
   Before the first change, John was in the #departments.John# Department<br>
</cfoutput>
<cfset Departments.John = "Marketing">
<cfoutput>
   After the first change, John is in the #departments.John# Department<br>
</cfoutput>
<cfset Departments["John"] = "Facilities">
<cfoutput>
   After the second change, John is in the #departments.John# Department<br>
</cfoutput>


Getting information about structures and keys

The following sections describe how to use ColdFusion functions to find information about structures and their keys.


Getting information about structures

To find out if a given value represents a structure, use the IsStruct function, as follows:

IsStruct(variable)

This function returns True if variable is a ColdFusion structure. (It also returns True if variable is a Java object that implements the java.util.Map interface.)

Structures are not indexed numerically, so to find out how many name-value pairs exist in a structure, use the StructCount function, as in the following example:

StructCount(employee)

To discover whether a specific Structure contains data, use the StructIsEmpty function, as follows:

StructIsEmpty(structure_name)

This function returns True if the structure is empty, and False if it contains data.


Finding a specific key and its value

To determine whether a specific key exists in a structure, use the StructKeyExists function, as follows:

StructKeyExists(structure_name, "key_name")

Note that you do not put the name of the structure in quotes, but you do put the key name in quotes. For example, the following code displays the value of the MyStruct.MyKey only if it exists:

<cfif StructKeyExists(myStruct, "myKey")>
<cfoutput> #mystruct.myKey#</cfoutput><br>
</cfif>

You can use the StructKeyExists function to dynamically test for keys by using a variable to represent the key name. In this case, you do not put the variable in quotes. For example, the following code loops through the records of the GetEmployees query and tests the myStruct structure for a key that matches the query’s LastName field. If ColdFusion finds a matching key, it displays the Last Name from the query and the corresponding entry in the structure.

<cfloop query="GetEmployees">
<cfif StructKeyExists(myStruct, LastName)>
<cfoutput>#LastName#: #mystruct[LastName]#</cfoutput><br>
</cfif>
</cfloop>

If the name of the key is known in advance, you can also use the ColdFusion IsDefined function, as follows:

IsDefined("structure_name.key")>

However, if the key is dynamic, or contains special characters, you must use the StructKeyExists function.

Note: Using StructKeyExists to test for the existence of a structure entry is more efficient than using IsDefined. ColdFusion scopes are available as structures and you can improve efficiency by using StructKeyExists to test for the existence of variables.


Getting a list of keys in a structure

To get a list of the keys in a CFML structure, you use the StructKeyList function, as follows:

<cfset temp=StructKeyList(structure_name, [delimiter] )>

You can specify any character as the delimiter; the default is a comma.

Use the StructKeyArray function to returns an array of keys in a structure, as follows:

<cfset temp=StructKeyArray(structure_name)>

Note: The StructKeyList and StructKeyArray functions do not return keys in any particular order. Use the ListSort or ArraySort functions to sort the results.


Copying structures

ColdFusion provides several ways to copy structures and create structure references. The following table lists these methods and describes their uses:

Technique
Use
Duplicate function
Makes a complete copy of the structure. All data is copied from the original structure to the new structure, including the contents of structures, queries, and other objects. As a result changes to one copy of the structure have no effect on the other structure.
This function is useful when you want to move a structure completely into a new scope. In particular, if a structure is created in a scope that requires locking (for example, Application), you can duplicate it into a scope that does not require locking (for example, Request), and then delete it in the scope that requires locking
StructCopy function
Makes a "shallow" copy of a structure. It creates a new structure and copies all simple variable and array values at the top level of the original structure to the new structure. However, it does not make copies of any structures, queries, or other objects that the original structure contains, or of any data inside these objects. Instead, it creates a reference in the new structure to the objects in the original structure. As a result, any change to these objects in one structure also changes the corresponding objects in the copied structure.
The Duplicate replaces this function for most, if not all, purposes.
Variable assignment
Creates an additional reference, or alias, to the structure. Any change to the data using one variable name changes the structure that you access using the other variable name.
This technique is useful when you want to add a local variable to another scope or otherwise change a variable’s scope without deleting the variable from the original scope.

The following example shows the different effects of copying, duplicating and assigning structure variables:

Create a new structure<br>
<cfset myNewStructure=StructNew()>
<cfset myNewStructure.key1="1">
<cfset myNewStructure.key2="2">
<cfset myArray=ArrayNew(1)>
<cfset myArray[1]="3">
<cfset myArray[2]="4">
<cfset myNewStructure.key3=myArray>
<cfset myNewStructure2=StructNew()>
<cfset myNewStructure2.Struct2key1="5">
<cfset myNewStructure2.Struct2key2="6">
<cfset myNewStructure.key4=myNewStructure2>
<cfdump var=#myNewStructure#><br>
<br>
A StructCopy copied structure<br>
<cfset CopiedStruct=StructCopy(myNewStructure)>
<cfdump var=#CopiedStruct#><br>
<br>
A Duplicated structure<br>
<cfset dupStruct=Duplicate(myNewStructure)>
<cfdump var=#dupStruct#><br>
<br>
A new reference to a structure<br>
<cfset structRef=myNewStructure>
<cfdump var=#structRef#><br>

<br>
Change a string, array element, and structure value in the StructCopy copy.<br>
<br>
<cfset CopiedStruct.key1="1A">
<cfset CopiedStruct.key3[2]="4A">
<cfset CopiedStruct.key4.Struct2key2="6A">
Original structure<br>
<cfdump var=#myNewStructure#><br>
Copied structure<br>
<cfdump var=#CopiedStruct#><br>
Duplicated structure<br>
<cfdump var=#DupStruct#><br>
Structure reference
<cfdump var=#structRef#><br>
<br>
Change a string, array element, and structure value in the Duplicate<br>
<br>
<cfset DupStruct.key1="1B">
<cfset DupStruct.key3[2]="4B">
<cfset DupStruct.key4.Struct2key2="6B">
Original structure<br>
<cfdump var=#myNewStructure#><br>
Copied structure<br>
<cfdump var=#CopiedStruct#><br>
Duplicated structure<br>
<cfdump var=#DupStruct#><br>
Structure reference
<cfdump var=#structRef#><br>
<br>
Change a string, array element, and structure value in the reference<br>
<br>
<cfset structRef.key1="1C">
<cfset structRef.key3[2]="4C">
<cfset structRef.key4.Struct2key2="6C">
Original structure<br>
<cfdump var=#myNewStructure#><br>
Copied structure<br>
<cfdump var=#CopiedStruct#><br>
Duplicated structure<br>
<cfdump var=#DupStruct#><br>
Structure reference
<cfdump var=#structRef#><br>
<br>
Clear the original structure<br>
<cfset foo=structclear(myNewStructure)>
Original structure:<br>
<cfdump var=#myNewStructure#><br>
Copied structure<br>
<cfdump var=#CopiedStruct#><br>
Duplicated structure<br>
<cfdump var=#DupStruct#><br>
Structure reference:<br>
<cfdump var=#structRef#><br>


Deleting structure elements and structures

To delete a key and its value from a structure, use the StructDelete function, as follows:

StructDelete(structure_name, key [, indicateNotExisting ])

The indicateNotExisting argument tells the function what to do if the specified key does not exist. By default, the function always returns True. However, if you specify True for the indicateNotExisting argument, the function returns True if the key exists and False if it does not.

You can also use the StructClear function to delete all the data in a structure but keep the structure instance itself, as follows:

StructClear(structure_name)

If you use StructClear to delete a structure that you have copied using the StructCopy function, the specified structure is deleted, but the copy is unaffected.

If you use StructClear to delete a structure that has a multiple references, the function deletes the contents of the structure and all references point to the empty structure, as shown by the following example:

<cfset myStruct.Key1="Macromedia">
Structure before StructClear<br>
<cfdump var="#myStruct#">
<cfset myCopy=myStruct>
<cfset StructClear(myCopy)>
After Clear:<br>
myStruct: <cfdump var="#myStruct#"><br>
myCopy: <cfdump var="#myCopy#">


Looping through structures

You can loop through a structure to output its contents as illustrated in the following example.

<!--- Create a structure and set its contents --->
<cfset departments=structnew()>

<cfset val=StructInsert(departments, "John", "Sales")>
<cfset val=StructInsert(departments, "Tom", "Finance")>
<cfset val=StructInsert(departments, "Mike", "Education")>

<!--- Build a table to display the contents --->
<cfoutput>
<table cellpadding="2" cellspacing="2">
   <tr>
      <td><b>Employee</b></td>
      <td><b>Department</b></td>
   </tr>
   <!--- Use cfloop to loop through the departments structure.
   The item attribute specifies a name for the structure key. --->
   <cfloop collection=#departments# item="person">
      <tr>
         <td>#person#</td>
         <td>#Departments[person]#</td>
      </tr>
   </cfloop>
</table>
</cfoutput>


Structure Example

Structures are particularly useful for grouping together a set of variables under a single name. The example in this section uses structures collect information from a form, and to submit that information to a custom tag, named cf_addemployee. For information on creating and using custom tags, see Creating and Using Custom CFML Tags.


Example file newemployee.cfm

This CFML page shows how to create structures and use them to add data to a database. It calls the cf_addemployee custom tag, which is defined in the addemployee.cfm file.

<html>
<head>
<title>Add New Employees</title>
</head>

<body>
<h1>Add New Employees</h1>
<!--- Action page code for the form at the bottom of this page --->

<!--- Establish parameters for first time through --->
<cfparam name="Form.firstname" default="">
<cfparam name="Form.lastname" default="">
<cfparam name="Form.email" default="">
<cfparam name="Form.phone" default="">
<cfparam name="Form.department" default="">

<!--- If at least the firstaname form field is passed, create
    a structure named employee and add values --->
<cfif #Form.firstname# eq "">
   <p>Please fill out the form.</p>
<cfelse>
  <cfoutput>
    <cfscript>
      employee=StructNew();
      employee.firstname = Form.firstname;
      employee.lastname = Form.lastname;
      employee.email = Form.email;
      employee.phone = Form.phone;
      employee.department = Form.department;
    </cfscript>

<!--- Display results of creating the structure --->
    First name is #StructFind(employee, "firstname")#<br>
    Last name is #StructFind(employee, "lastname")#<br>
    EMail is #StructFind(employee, "email")#<br>
    Phone is #StructFind(employee, "phone")#<br>
    Department is #StructFind(employee, "department")#<br>
   </cfoutput>

  <!--- Call the custom tag that adds employees --->
   <cf_addemployee empinfo="#employee#">
</cfif>

<!--- The form for adding the new employee information --->
<hr>
<form action="newemployee.cfm" method="Post">
First Name:&nbsp;
<input name="firstname" type="text" hspace="30" maxlength="30"><br>
Last Name:&nbsp;
<input name="lastname" type="text" hspace="30" maxlength="30"><br>
EMail:&nbsp;
<input name="email" type="text" hspace="30" maxlength="30"><br>
Phone:&nbsp;
<input name="phone" type="text" hspace="20" maxlength="20"><br>
Department:&nbsp;
<input name="department" type="text" hspace="30" maxlength="30"><br>

<input type="Submit" value="OK">
</form>
<br>
</body>
</html>


Reviewing the code

The following table describes the code:

Code
Description
<cfparam name="Form.firstname" default="">
<cfparam name="Form.lastname" default="">
<cfparam name="Form.email" default="">
<cfparam name="Form.phone" default="">
<cfparam name="Form.department" default="">
Set default values of all form fields so that they exist the first time this page is displayed and can be tested.
<cfif #form.firstname# eq "">
 Please fill out the form.<br>
Test the value of the form’s firstname field. This field is required. The test is False the first time the page displays.
If there is no data in the Form.firstname variable, display a message requesting the user to fill the form.
<cfelse>
 <cfoutput>
  <cfscript>
   employee=StructNew();
   employee.firstname = Form.firstname;
   employee.lastname = Form.lastname;
   employee.email = Form.email;
   employee.phone = Form.phone;
   employee.department = Form.department;
  </cfscript>

  First name is #employee.firstname#<br>
  Last name is #employee.lastname#<br>
  EMail is #employee.email#<br>
  Phone is #employee.phone#<br>
  Department is #employee.department#<br>
 </cfoutput>
If Form.firstname contains text, the user submitted the form.
Use CFScript to create a new structure named employee and fill it with the form field data.
Then display the contents of the structure
 cf_addemployee empinfo="#duplicate(employee)#">
</cfif>
Call the cf_addemployee custom tag and pass it a copy of the employee structure in the empinfo attribute.
The duplicate function ensures that the custom tag gets a copy of the employee structure, not the original. While this is not necessary in this example, it is good practice because it prevents the custom tag from modifying the calling page’s structure contents.
<form action="newemployee.cfm" method="Post">
First Name:&nbsp;
<input name="firstname" type="text" hspace="30"
   maxlength="30"><br>
Last Name:&nbsp;
<input name="lastname" type="text" hspace="30"
   maxlength="30"><br>
EMail:&nbsp;
<input name="email" type="text" hspace="30"
   maxlength="30"><br>
Phone:&nbsp;
<input name="phone" type="text" hspace="20"
   maxlength="20"><br>
<p>Department:&nbsp;
<input name="department" type="text" hspace="30"
   maxlength="30"><br>
<br>
<input type="Submit" value="OK">
</form>
The data form. When the user clicks Submit, the form posts the data to this ColdFusion page.


Example file addemployee.cfm

This file is an example of a custom tag used to add employees. Employee information is passed through the employee structure (the empinfo attribute). For databases that do not support automatic key generation, you must also add the Emp_ID.

<cfif StructIsEmpty(attributes.empinfo)>
   <cfoutput>
      Error. No employee data was passed.<br>
   </cfoutput>
   <cfexit method="ExitTag">
<cfelse>
   <!--- Add the employee --->
   <cfquery name="AddEmployee" datasource="cfsnippets">
      INSERT INTO Employees
         (FirstName, LastName, Email, Phone, Department)
      VALUES (
      '#attributes.empinfo.firstname#' ,
      '#attributes.empinfo.lastname#' ,
      '#attributes.empinfo.email#' ,
      '#attributes.empinfo.phone#' ,
      '#attributes.empinfo.department#' )
   </cfquery>
</cfif>
<cfoutput>
   <hr>Employee Add Complete
</cfoutput>


Reviewing the code

The following table describes the code:

Code
Description
<cfif StructIsEmpty(Attributes.empinfo)>
  <cfoutput>
   Error. No employee data was passed.
  </cfoutput>
  <cfexit method="ExitTag">
If the custom tag was called without an empinfo attribute, display an error message and exit the tag.
<cfelse>
  <cfquery name="AddEmployee" datasource=
     "cfsnippets">
   INSERT INTO Employees
     (FirstName, LastName, Email, Phone,
      Department)
   VALUES (
     '#attributes.empinfo.firstname#' ,
     '#attributes.empinfo.lastname#' ,
     '#attributes.empinfo.email#' ,
     '#attributes.empinfo.phone#' ,
     '#attributes.empinfo.department#' )
   </cfquery>
</cfif>
Add the employee data passed in the empinfo structure to the Employees table of the cfsnippets database.
Use direct references to the structure entries, not structfind functions.
If the database does not support automatic generation of the Emp_ID key, you must add an Emp_ID entry to the form and add it to the query.
<cfoutput>
   <hr>Employee Add Complete
</cfoutput>
Display a completion message. This code does not have to be inside the cfelse block because the cfexit tag prevents it from being run if the empinfo structure is empty.


Structure Functions

You can use the following functions to create and manage structures in ColdFusion applications. The table describes each function’s purpose and provides specific, but limited, information that may assist you in determining whether to use the function instead of other techniques

Function
Description
Duplicate
Returns a complete copy of the structure.
IsStruct
Returns True if the specified variable is a ColdFusion structure or a Java object that implements the java.util.Map interface.
StructAppend
Appends one structure to another.
StructClear
Removes all data from the specified structure.
StructCopy
Returns a "shallow" copy of the structure. All embedded objects are references to the objects in the original structure. The Duplicate function has replaced this function for most purposes.
StructCount
Returns the number of keys in the specified structure.
StructDelete
Removes the specified item from the specified structure.
StructFind
Returns the value associated with the specified key in the specified structure. This function is redundant with accessing structure elements using associative array notation.
StructFindKey
Searches through a structure for the specified key name and returns an array containing data on the found key or keys.
StructFindValue
Searches through a structure for the specified simple data value (for example, a string or number) and returns an array containing information on the value location in the structure.
StructGet
Returns a reference to a substructure contained in a structure at the specified path. This function is redundant with using direct reference to a structure. If you accidentally use this function on a variable that is not a structure, it replaces the value with an empty structure.
StructInsert
Inserts the specified key-value pair into the specified structure. Unlike a direct assignment statement, this function generates an error by default if the specified key exists in the structure.
StructIsEmpty
Indicates whether the specified structure contains data. Returns True if the structure contains no data, and False if it does contain data.
StructKeyArray
Returns an array of keys in the specified structure.
StructKeyExists
Returns True if the specified key is in the specified structure. You can use this function in place of the IsDefined function to check for the existence of variables in scopes that are available as structures.
StructKeyList
Returns a list of keys in the specified structure.
StructNew
Returns a new structure.
StructSort
Returns an array containing the key names of a structure in the order determined by the sort criteria.
StructUpdate
Updates the specified key with the specified value. Unlike a direct assignment statement, this function generates an error if the structure or key does not exist.

Note that all functions except StructDelete throw an exception if a referenced key or structure does not exist.

For more information on these functions, see the CFML Reference.

Previous


Extending ColdFusion Pages with CFML Scripting

ColdFusion offers a server-side scripting language, CFScript, that provides ColdFusion functionality in script syntax. This JavaScript-like language gives developers the same control flow as ColdFusion, but without tags. You can also use CFScript to write user-defined functions that you can use anywhere a ColdFusion expression is allowed.

This chapter describes the CFScript language's functionality and syntax, and provides information on using CFScript effectively in ColdFusion pages.

Contents
  • About CFScript
  • The CFScript Language
  • Using CFScript Statements
  • Handling exceptions
  • CFScript Example
Next


About CFScript

CFScript is a language within a language. CFScript is a scripting language that is similar to JavaScript but is simpler to use. Also, unlike JavaScript, CFScript only runs on the ColdFusion Server; it does not run on the client system. CFScript code can use all ColdFusion functions and expressions, and has access to all ColdFusion variables that are available in the script’s scope.

CFScript provides a compact and efficient way to write ColdFusion logic. Typical uses of CFScript include:

  • Simplifying and speeding variable setting
  • Building compact JavaScript-like flow control structures
  • Creating user-defined functions

Because you use functions and expressions directly in CFScript, you do not have to surround each assignment or function in a cfset tag. Also, CFScript assignments are often faster than cfset tags.

CFScript provides a set of decision and flow-control structures that are more familiar than ColdFusion tags to most programmers.

In addition to variable setting, other operations tend to be slightly faster in CFScript than in tags.

ColdFusion 5 and later releases allow you to use CFScript to create user-defined functions, or UDFs (also known as custom functions). You call UDFs in the same manner that you call standard ColdFusion functions. UDFs are to ColdFusion built-in functions what custom tags are to ColdFusion built-in tags. Typical uses of UDFs include data manipulation and mathematical calculation routines.

You cannot include ColdFusion tags in CFScript. However, a number of functions and CFScript statements are equivalent to commonly used tags. For more information, see CFScript functional equivalents to ColdFusion tags.


Comparing tags and CFScript

The following examples show how you can use CFML tags and CFScript to do the same thing. Each example takes data submitted from a form and puts it in a structure; if the form does not have a last name and department field, it displays a message:

Using CFML tags

<cfif IsDefined("Form.submit")>
     <cfif (Form.lastname NEQ "") AND (Form.department NEQ "")>
      <cfset employee=structnew()>
      <cfset employee.firstname=Form.firstname>
      <cfset employee.lastname=Form.lastname>
      <cfset employee.email=Form.email>
      <cfset employee.phone=Form.phone>
      <cfset employee.department=Form.department>
      <cfoutput>
         Adding #Form.firstname# #Form.lastname#<br>
      </cfoutput>
   <cfelse>
      <cfoutput>
         You must enter a Last Name and Department.<br>
      </cfoutput>
    </cfif>
</cfif>

Using CFScript

<cfscript>
   if (IsDefined("Form.submit"))
      {
      if ((Form.lastname NEQ "") AND (Form.department NEQ ""))
         {
         employee=StructNew();
         employee.firstname=Form.firstname;
         employee.lastname=Form.lastname;
         employee.email=Form.email;
         employee.phone=Form.phone;
         employee.department=Form.department;
         WriteOutput("Adding #Form.firstname# #Form.lastname# <br>");
         }
      else
         WriteOutput("You must enter a Last Name and Department.<br>");
      }
</cfscript>


The CFScript Language

This section explains the syntax of the CFScript language.


Identifying CFScript

You enclose CFScript regions inside <cfscript> and </cfscript> tags. No other CFML tags are allowed inside a cfscript region. The following lines show a minimal script:

<cfscript>
a = 2;
</cfscript>


Variables

CFScript variables can be of any ColdFusion type, such as numbers, strings, arrays, queries, and objects. The CFScript code can read and write any variables that are available in the page that contains the script. This includes all common scope variables, such as Session, Application, and Server variables.


Expressions

CFScript supports all CFML expressions. CFML expressions include operators (such as +, -, EQ, and so on), as well as all CFML functions. As in all ColdFusion expressions, you must use CFML operators, such as LT, GT, and EQ. You cannot use JavaScript operators, such as <, >, ==, or ++.

For information about CFML expressions, operators, and functions, see Using Expressions and Pound Signs.


Statements

CFScript supports the following statements:

assignment | for-in | try-catch
function call | while | function (function definition)
if-else | do-while | var (in custom functions only)
switch-case | break | return (in custom functions only)
for | continue |

The following rules apply to statements:

  • You must put a semicolon at the end of a statement.
  • Line breaks are ignored. A single statement can cross multiple lines.
  • White space is ignored. For example, it does not matter whether you precede a semicolon with a space character.
  • Use curly braces to group multiple statements together into one logical statement unit.
  • Unless otherwise indicated, you can use any ColdFusion expression in the body of a statement.

Note: This chapter documents all statements except var and return. For information on these statements, see Defining functions in CFScript.


Statement Blocks

Curly brace characters ({ and }) group multiple CFScript statements together so that they are treated as a single unit or statement. This enables you to create code blocks in conditional statements, such as the following:

if(score GT 0)
{
   result = "positive";
   Positives = Positives + 1;
}

In this example, both assignment statements are executed if the score is greater than 0. If they were not in the code block, only the first line would execute.

You do not have to put brace characters on their own lines in the code. For example, you could put the open brace in the preceding example on the same line as the if statement, and some programmers use this style. However, putting at least the ending brace on its own line makes it easier to read the code and separate out code blocks.


Comments

CFScript has two forms of comments: single line and multiline.

A single line comment begins with two forward slashes (//) and ends at the line end. For example:

//This is a single line comment.
//This is a second single line comment.

A multiline comment starts with a /* marker and continues until it reaches a */ marker. For example:

/*This is a multiline comment.
  You do not need to start each line with a comment indicator.
  This is the last line in the comment. */

The following rules apply to comments:

  • Comments do not have to start at the beginning of a line. They can follow active code on a line. For example, the following line is valid:
    • MyVariable = 12; // Set MyVariable to the default value.
  • The end of a multiline comment can be followed on the same line by active code. For example, the following line is valid, although it is poor coding practice:
    • End of my long comment */ foo = "bar";
  • You can use multiline format for a comment on a single line, for example:
    • /*This is a single line comment using multiline format. */
  • You cannot nest /* and */ markers inside other comment lines.


Reserved words

In addition to the names of ColdFusion functions and words reserved by ColdFusion expressions (such as NOT, AND, IS, and so on), the following words are reserved in CFScript. Do not use these words as variables or identifiers in your scripting code:

break | default | function | switch
case | do | if | try
catch | else | in | var
continue | for | return | while


Differences from JavaScript

Although CFScript and JavaScript are similar, they have several key differences. The following list identifies CFScript features that differ from JavaScript.

  • CFScript uses ColdFusion expressions, which are neither a subset nor a superset of JavaScript expressions. For example, there is no < operator in CFScript; you use the LT operator instead.
  • Variable declarations are only used in user-defined functions.
  • CFScript is case-insensitive.
  • All statements end with a semicolon and line breaks in the code are ignored.
  • Assignments are statements, not expressions.
  • JavaScript objects, such as Window and Document, are not available.
  • Only the ColdFusion Server processes CFScript. There is no client-side CFScript.


CFScript limitation

You cannot include ColdFusion tags in CFScript. However, you can include cfscript blocks inside other ColdFusion tags, such as cfoutput.


CFScript functional equivalents to ColdFusion tags

Although you cannot use ColdFusion tags in CFSCript, CFSCript and ColdFusion functions provide equivalents to several commonly-used CFML tags. The following table lists ColdFusion tags with equivalent functions or CFScript statements:

Tag
CFScript Equivalent
cfset
Direct assignment, such as Myvar=1;
cfoutput
WriteOutput function
cfif, cfelseif, cfelse
if and else statements
cfswitch, cfcase,
cfdefaultcase
switch, case, and default statements
Indexed cfloop
for loops
Conditional cfloop
while loops and do while loops
Structure cfloop
for in loop. )There is no equivalent for queries, lists, or objects.)
cfbreak
break statement. Note that CFScript also has a continue statement that has no equivalent CFML tag.
cftry, cfcatch
try and catch statements
cfcookie
Direct assignment of Cookie scope memory-only variables. You cannot use direct assignment to set persistent cookies that are stored on the user’s system.
cfobject
CreateObject function


Using CFScript Statements

The following sections describe how to use these CFScript statements:

  • Assignment statements and functions
  • Conditional processing statements
  • Looping statements


Using assignment statements and functions

CFScript assignment statements are the equivalent of the cfset tag. These statements have the following form:

lval = expression;

lval is any ColdFusion variable reference. For example:

x = "positive";
y = x;
a[3]=5;
structure.member=10;
ArrayCopy=myArray;

You can use ColdFusion function calls, including UDFs, directly in CFScript. For example, the following line is a valid CFScript statement:

StructInsert(employee,"lastname",FORM.lastname);


Using conditional processing statements

CFScript includes the following conditional processing statements:

  • if and else statements, which serve the same purpose as the cfif, cfelseif, and cfelse tags
  • switch, case, and default statements, which are the equivalents of the cfswitch, cfcase, and cfdefaultcase tags


Using if and else statements

The if and else statements have the following syntax:

if(expr) statement [else statement]

In its simplest form, an if statement looks like this:

if(value EQ 2700)
   message = "You’ve reached the maximum";

A simple if-else statement looks like the following:

if(score GT 1)
   result = "positive";
else
   result = "negative";

CFScript does not include an elseif statement. However, you can use an if statement immediately after an else statement to create the equivalent of a cfelseif tag, as the following example shows:

if(score GT 1)
   result = "positive";
else if(score EQ 0)
   result = "zero";
else
   result = "negative";

As with all conditional processing statements, you can have multiple statements for each condition, as follows:

if(score GT 1)
   {
   result = "positive";
   message = "The result was positive.";
else
   {
   result = "negative";
   message = "The result was negative.";
   }

Note: Often, you can make your code clearer by using braces even where they are not required.


Using switch and case statements

The switch statement and its dependent case and default statements have the following syntax:

switch (expression) {
   case constant: [case constant:]... statement(s) break;
   [case constant: [case constant:]... statement(s) break;]...
   [default: statement(s)] }

Use the following rules and recommendations for switch statements:

  • You cannot mix Boolean and numeric constant values in a switch statement.
  • Each constant value must be a constant (that is, not a variable, a function, or other expression).
  • Multiple case constant: statements can precede the statement or statements to execute if any of the cases are true. This lets you specify several matches for one code block.
  • No two constant values can be the same.
  • The statements following the colon in a case statement block do not have to be in braces. If a constant value equals the switch expression, ColdFusion executes all statements through the break statement.
  • The break statement at the end of the case statement tells ColdFusion to exit the switch statement. ColdFusion does not generate an error message if you omit a break statement. However, if you omit it, ColdFusion executes all the statements in the following case statement, even if that case is false. In nearly all circumstances, this is not what you want to do.
  • You can have only one default statement in a switch statement block. ColdFusion executes the statements in the default block if none of the case statement constants equals the expression value.
  • The default statement does not have to follow all switch statements, but it is good programming practice to do so. If any switch statements follow the default statement you must end the default block code with a break statement.
  • The default statement is not required. However, you should use one if the case constants do not include all possible values of the expression.
  • The default statement does not have to follow all the case statements; however, it is good programming practice to put it there.

The following switch statement takes the value of a name variable.

  1. If the name is John or Robert, it sets both the male variable and the found variable to True.
  2. If the name is Mary, it sets the male variable to False and the found variable to True.
  3. Otherwise, it sets the found variable to False.
switch(name)
{
   case "John": case "Robert":
      male=True;
      found=True;
      break;
   case "Mary":
      male=False;
      found=True;
      break;
   default:
      found=False;
} //end switch


Using looping statements

CFScript provides a richer selection of looping constructs than those supplied by CFML tags. It enables you to create efficient looping constructs similar to those in most programming and scripting languages. CFScript provides the following looping constructs:

  • For
  • While
  • Do-while
  • For-in

CFScript also includes the continue and break statements that control loop processing.

The following sections describe these types of loops and their uses.


Using for loops

The for loop has the following format:

for (inital-expression; test-expression; final-expression) statement

The initial-expression and final-expression can be one of the following:

  • A single assignment expression; for example, x=5 or loop=loop+1
  • Any ColdFusion expression; for example, SetVariable("a",a+1)
  • Empty

The test-expression can be one of the following:

  • Any ColdFusion expression; for example:
    • A LT 5
index LE x
status EQ "not found" AND index LT end
  • Empty

Note: The test expression is re-evaluated before each repeat of the loop. If code inside the loop changes any part of the test expression, it may affect the number of iterations in the loop

The statement can be a single semicolon terminated statement or a statement block in curly braces.

When ColdFusion executes a for loop it does the following:

  1. Evaluates the initial expression.
  2. Evaluates the test-expression.
  3. If the test-expression is False, exits the loop and processing continues following the statement.
    4. If the test-expression is True:
    1. Executes the statement (or statement block).
    2. Evaluates the final-expression.
    3. Returns to step 2.

For loops are most commonly used for processing in which an index variable is incremented each time through the loop, but it is not limited to this use.

The following simple for loop sets each element in a 10-element array with its index number.

for(index=1;
   index LT 10;
   index = index + 1)
   a[index]=index;

The following, more complex, example demonstrates two features:

  • The use of curly braces to group multiple statements into a single block.
  • An empty condition statement. All loop control logic is in the statement block.
<cfscript>
strings=ArrayNew(1);
ArraySet(strings, 1, 10, "lock");
strings[5]="key";
indx=0;
for( ; ; )
{
   indx=indx+1;
   if(Find("key",strings[indx],1)) {
      WriteOutput("Found key at " & indx & ".<br>");
      break;
      }
   else if (indx IS ArrayLen(strings))
      {
      WriteOutput("Exited at " & indx & ".<br>");
      break;
      }
}
</cfscript>

This example shows one important issue you must remember when creating loops: you must always ensure that the loop ends. If this example lacked the else if statement, and there was no “key” in the array, ColdFusion would loop forever or until a system error occurred; you would have to stop the server to end the loop.

The example also shows two issues with index arithmetic: in this form of loop you must make sure to initialize the index, and you must keep track of where the index is incremented. In this case, because the index is incremented at the top of the loop, you must initialize it to 0 so it becomes 1 in the first loop.


Using while loops

The while loop has the following format:

while (expression) statement

The while statement does the following:

  1. Evaluates the expression.
  2. If the expression is True, it does the following:
    1. Executes the statement, which can be a single semicolon-terminated statement or a statement block in curly braces.
    2. Returns to step 1.
      3. If the expression is False, processing continues with the next statement.

The following example uses a while loop to populate a 10-element array with multiples of five.

a = ArrayNew(1);
loop = 1;
while (loop LE 10)
{
 a[loop] = loop * 5;
 loop = loop + 1;
}

As with other loops, you must make sure that at some point the while expression is False and you must be careful to check your index arithmetic.


Using do-while loops

The do-while loop is like a while loop, except that it tests the loop condition after executing the loop statement block. The do-while loop has the following format:

do statement while (expression);

The do while statement does the following:

  1. Executes the statement, which can be a single semicolon-terminated statement or a statement block in curly braces.
  2. Evaluates the expression.
  3. If the expression is true, it returns to step 1.
    4. If the expression is False, processing continues with the next statement.

The following example, like the while loop example, populates a 10-element array with multiples of five:

a = ArrayNew(1);
loop = 1;
do
{
  a[loop] = loop * 5;
  loop = loop + 1;
}
while (loop LE 10);

Note that because the loop index increment follows the array value assignment, the example initializes the loop variable to 1 and tests to make sure that it is less than or equal to 10.

The following example generates the same results as the previous two examples, but it increments the index before assigning the array value. As a result, it initializes the index to 0, and the end condition tests that the index is less than 10.

a = ArrayNew(1);
loop = 0;
do {loop = loop + 1; a[loop] = loop * 5;} while (loop LT 10);


using for-in loops

The for-in loop loops over the elements in a ColdFusion structure. It has the following format:

for (variable in structure) statement

The variable can be any ColdFusion identifier; it holds each structure key name as ColdFusion loops through the structure. The structure must be the name of an existing ColdFusion structure. The statement can be a single semicolon terminated statement or a statement block in curly braces.

The following example creates a structure with three elements. It then loops through the structure and displays the name and value of each key. Although the curly braces are not required here, they make it easier to determine the contents of the relatively long WriteOutput function. In general, you can make structured control flow, especially loops, clearer by using curly braces.

myStruct=StructNew();
myStruct.productName="kumquat";
mystruct.quality="fine";
myStruct.quantity=25;
for (keyName in myStruct)
{
   WriteOutput("myStruct." & Keyname & " has the value: " &
      myStruct[keyName] &"<br>");
}

Note: Unlike the cfloop tag, you cannot use the CFSCript for-in loops to loop over a query, list, or object.


using continue and break statements

The continue and break statements enable you to control the processing inside loops:

  • The continue statement tells ColdFusion to skip to the beginning of the next loop iteration.
  • The break statement exits the current loop or case statement.


Using continue

The continue statement ends the current loop iteration, skips any code following it in the loop, and jumps to the beginning of the next loop iteration. For example, the following code loops through an array and display’s each value that is not an empty string.

for ( loop=1; loop LE 10; loop = loop+1)
{
   if(a[loop] EQ "") continue;
   WriteOutput(loop);
}

(To test this code snippet, you must first create an array, a, with 10 or more elements, some of which are not empty strings.)

In general, the continue statement is particularly useful if you loop over arrays or structures and you want to skip processing for array elements or structure members with specific values, such as the empty string.


Using break

The break statement exits the current loop or case statement. Processing continues at the next CFScript statement. You end case statement processing blocks with a break statement. You can also use a test case with a break statement to prevent infinite loops, as shown in the following example. This script loops through an array and prints out the array indexes that contain the value “key”. It uses a conditional test and a break statement to make sure that the loop ends when at the end of the array.

strings=ArrayNew(1);
ArraySet(strings, 1, 10, "lock");
strings[5]="key";
strings[9]="key";
indx=0;
for( ; ; )
{
   indx=indx+1;
   if(Find("key",strings[indx],1))
   {
      WriteOutput("Found a key at " & indx & ".<br>");
      }
   else if (indx IS ArrayLen(strings))
   {
      WriteOutput("Array ends at index " & indx & ".<br>");
      break;
   }
}


Handling exceptions

Note: This section does not explain exception handling concepts. For a discussion of exception handling in ColdFusion, see Handling Errors.

ColdFusion provides two statements for exception handling in CFScript: try and catch. These statements are equivalent to the CFML cftry and cfcatch tags.


Exception handling syntax and rules

Exception-handling code in CFScript has the following format:

try
{
   Code where exceptions will be caught
}
catch(exceptionType exceptionVariable)
{
   Code to handle exceptions of type exceptionType that occur in the try
   block
}
...
catch(exceptionTypeN exceptionVariableN)
{
   Code to handle exceptions of type exceptionTypeN that occur in the try
   block
}

Note: In CFScript, catch statements follow the try block; you do not put them inside the try block. This structure differs from that of the cftry tag, which must include the cfcatch tags in its body.

When you have a try statement, you must have a catch statement. In the catch block, the exceptionVariable variable contains the exception type. This variable is the equivalent of the cfcatch tag cfcatch.Type built-in variable.


Exception handling example

The following code illustrates exception handling in CFScript. It uses a CreateObject function to create a Java object. The catch statement executes only if the CreateObject function generates an exception.The displayed information includes the exception message; the except.Message variable is the equivalent of calling the Java getMessage method on the returned Java exception object.

<cfscript>
   try
   {
      emp = CreateObject("Java", "Employees");
   }
   catch(Any excpt)
   {
      WriteOutput("The application was unable to perform a required operation.<br>
Please try again later.<br>If this problem persists, contact
Customer Service and include the following information:<br>
         #excpt.Message#<br>");
   }
</cfscript>


CFScript Example

The example in this section uses the following CFScript features:

  • Variable assignment
  • Function calls
  • For loops
  • If-else statements
  • WriteOutput functions
  • Switch statements

The example uses CFScript without any other ColdFusion tags. It creates a structure of course applicants. This structure contains two arrays; the first has accepted students, the second has rejected students. The script also creates a structure with rejection reasons for some (but not all) rejected students. It then displays the accepted applicants followed by the rejected students and their rejection reasons.

<html>
<head>
   <title>CFScript Example</title>
</head>
<body>
<cfscript>

   //Set the variables

   acceptedApplicants[1] = "Cora Cardozo";
   acceptedApplicants[2] = "Betty Bethone";
   acceptedApplicants[3] = "Albert Albertson";
   rejectedApplicants[1] = "Erma Erp";
   rejectedApplicants[2] = "David Dalhousie";
   rejectedApplicants[3] = "Franny Farkle";
   applicants.accepted=acceptedApplicants;
   applicants.rejected=rejectedApplicants;

   rejectCode=StructNew();
   rejectCode["David Dalhousie"] = "score";
   rejectCode["Franny Farkle"] = "too late";

   //Sort and display accepted applicants

   ArraySort(applicants.accepted,"text","asc");
   WriteOutput("The following applicants were accepted:<hr>");
   for (j=1;j lte ArrayLen(applicants.accepted);j=j+1)
   {
      WriteOutput(applicants.accepted[j] & "<br>");
   }
   WriteOutput("<br>");

   //sort and display rejected applicants with reaons information

   ArraySort(applicants.rejected,"text","asc");
   WriteOutput("The following applicants were rejected:<hr>");
   for (j=1;j lte ArrayLen(applicants.rejected);j=j+1)
   {
      applicant=applicants.rejected[j];
      WriteOutput(applicant & "<br>");
      if (StructKeyExists(rejectCode,applicant))
      {
         switch(rejectCode[applicant])
         {
            case "score":
               WriteOutput("Reject reason: Score was too low.<br>");
               break;
            case "late":
               WriteOutput("Reject reason: Application was late.<br>");
               break;
            default:
               WriteOutput("Rejected with invalid reason code.<br>");
         } //end switch
      } //end if
      else
      {
         WriteOutput("Reject reason was not defined.<br>");
      } //end else
      WriteOutput("<br>");
   } //end for
</cfscript>


Reviewing the code

The following table describes the code:

Code
Description
<cfscript>
acceptedApplicants[1] = "Cora Cardozo";
acceptedApplicants[2] = "Betty Bethone";
acceptedApplicants[3] = "Albert Albertson";
rejectedApplicants[1] = "Erma Erp";
rejectedApplicants[2] = "David Dalhousie";
rejectedApplicants[3] = "Franny Farkle";
applicants.accepted=acceptedApplicants;
applicants.rejected=rejectedApplicants;

rejectCode=StructNew();
rejectCode["David Dalhousie"] = "score";
rejectCode["Franny Farkle"] = "too late";
Creates two one-dimensional arrays, one with the accepted applicants and another with the rejected applicants. The entries in each array are in random order.
Creates a structure and assign each array to an element of the structure.
Creates a structure with rejection codes for rejected applicants. The rejectedCode structure does not have entries for all rejected applicants, and one of its values does not match a valid code. The structure element references use associative array notation in order to use key names that contain spaces.
ArraySort(applicants.accepted,"text","asc");
WriteOutput("The following applicants were accepted:<hr>");
for (j=1;j lte ArrayLen(applicants.accepted);j=j+1)
{
  WriteOutput(applicants.accepted[j] & "<br>");
}
WriteOutput("<br>");
Sorts the accepted applicants alphabetically.
Displays a heading
Loops through the accepted applicants and writes their names. Braces enhance clarity, although they are not needed for a single statement loop.
Writes an additional line break at the end of the list of accepted applicants.
ArraySort(applicants.rejected,"text","asc");
WriteOutput("The following applicants were rejected:<hr>");
Sorts rejectedApplicants array alphabetically and writes a heading.
for (j=1;j lte ArrayLen(applicants.rejected);j=j+1)
{
  applicant=applicants.rejected[j];
  WriteOutput(applicant & "<br>");
Loops through the rejected applicants.
Sets the applicant variable to the applicant name. This makes the code clearer and enables you to easily reference the rejectCode array later in the block.
Writes the applicant name.
if (StructKeyExists(rejectCode,applicant))
{
  switch(rejectcode[applicant])
  {
    case "score":
      WriteOutput("Reject reason: Score was too low.<br>");
      break;
    case "late":
      WriteOutput("Reject reason: Application was
         late.<br>");
      break;
    default:
      WriteOutput("Rejected with invalid reason code.<br>");
  } //end switch
} //end if
Checks the rejectCode structure for a rejection code for the applicant.
If a code exists, enters a switch statement that examines the rejection code value.
If the rejection code value matches one of the known codes, displays an expanded explanation of the meaning. Otherwise (the default case), displays an indication that the rejection code is not valid.
Comments at the end of blocks help clarify the control flow.
else
{
  WriteOutput("Reject reason was not defined. <br>");
{
If there is no entry for the applicant in the rejectCode structure, displays a message indicating that the reason was not defined.
      WriteOutput("<br>");
} //end for
</cfscript>
Displays a blank line after each rejected applicant.
Ends the for loop that handles each rejected applicant.
Ends the CFScript.

  Previous


Using Regular Expressions in Functions

Regular expressions let you perform string matching operations using ColdFusion functions. This chapter describes how regular expressions work with the following functions:

  • REFind
  • REFindNoCase
  • REReplace
  • REReplaceNoCase

This chapter does not apply to regular expressions used in the cfinput and cftextinput tags. These tags use JavaScript regular expressions, which have a slightly different syntax than ColdFusion regular expressions. For information on JavaScript regular expressions, see Building Dynamic Forms.

Contents
  • About regular expressions
  • Regular expression syntax
  • Using backreferences
  • Returning matched subexpressions
  • Regular expression examples
  • Types of regular expression technologies
Next


About regular expressions

In traditional string matching, as used by the ColdFusion Find and Replace functions, you provide the string pattern to search for and the string to search. The following example searches a string for the pattern " BIG " and returns a string index if found. The string index is the location in the search string where the string pattern begins.

<cfset IndexOfOccurrence=Find(" BIG ", "Some BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

You must provide the exact string pattern to match. If the exact pattern is not found, Find returns an index of 0. Because you must specify the exact string pattern to match, matches for dynamic data can be very difficult, if not impossible, to construct.

The next example uses a regular expression to perform the same search. This example searches for the first occurrence in the search string of any string pattern that consists entirely of uppercase letters enclosed by spaces:

<cfset IndexOfOccurrence=REFind(" [A-Z]+ ", "Some BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

The regular expression " [A-Z]+ " matches any string pattern consisting of a leading space, followed by any number of uppercase letters, followed by a trailing space. Therefore, this regular expression matches the string " BIG " and any string of uppercase letters enclosed in spaces.

By default, the matching of regular expressions is case sensitive. You can use the case-insensitive functions, REFindNoCase and REReplaceNoCase, for case-insensitive matching.

Because you often process large amounts of dynamic textual data, regular expressions are invaluable in writing complex ColdFusion applications.


Using ColdFusion regular expression functions

ColdFusion supplies four functions that work with regular expressions:

  • REFind
  • REFindNoCase
  • REReplace
  • REReplaceNoCase

REFind and REFindNoCase use a regular expression to search a string for a pattern and return the string index where it finds the pattern. For example, the following function returns the index of the first instance of the string " BIG ":

<cfset IndexOfOccurrence=REFind(" BIG ", "Some BIG BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

To find the next occurrence of the string " BIG ", you must call the REFind function a second time. For an example of iterating over a search string to find all occurrences of the regular expression, see Returning matched subexpressions.

REReplace and REReplaceNoCase use regular expressions to search through a string and replace the string pattern that matches the regular expression with another string. You can use these functions to replace the first match, or to replace all matches.

For detailed descriptions of the ColdFusion functions that use regular expressions, see the CFML Reference.


Basic regular expression syntax

The simplest regular expression contains only a literal characters. The literal characters must match exactly the text being searched. For example, you can use the regular expression function REFind to find the string pattern " BIG ", just as you can with the Find function:

<cfset IndexOfOccurrence=REFind(" BIG ", "Some BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

In this example, REFind must match the exact string pattern " BIG ".

To use the full power of regular expressions, combine literal characters with character sets and special characters, as in the following example:

<cfset IndexOfOccurrence=REFind(" [A-Z]+ ", "Some BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

The literal characters of the regular expression consists of the space characters at the beginning and end of the regular expression. The character set consists of that part of the regular expression in square brackets. This character set specifies to find a single uppercase letter from A to Z, inclusive. The plus sign (+) after the square brackets is a special character specifying to find one or more occurrences of the character set.

If you removed the + from the regular expression in the previous example, " [A-Z] " matches a literal space, followed by any single uppercase letter, followed by a single space. This regular expression matches " B " but not " BIG ". The REFind function returns 0 for the regular expression, meaning that it did not find a match.

You can construct very complicated regular expressions containing literal characters, character sets, and special characters. Like any programming language, the more you work with regular expressions, the more you can accomplish with them. The examples in this section are fairly basic. For more examples, see Regular expression examples.


Regular expression syntax

This section describes the basic rules for creating regular expressions.


Using character sets

The pattern within the square brackets of a regular expression defines a character set that is used to match a single character. For example, the regular expression " [A-Za-z] " specifies to match any single uppercase or lowercase letter enclosed by spaces. In the character set, a hyphen indicates a range of characters.

The regular expression " B[IAU]G " matches the strings " BIG ", " BAG ", and " BUG ", but does not match the string " BOG ".

If you specified the regular expression as " B[IA][GN] ", the concatenation of character sets creates a regular expression that matches the corresponding concatenation of characters in the search string. This regular expression matches a space, followed by "B", followed by an "I" or "A", followed by a "G" or "N", followed by a trailing space. The regular expression matches " BIG ", "BAG ", "BIN ", and "BAN ".

The regular expression [A-Z][a-z]* matches any word that starts with an uppercase letter and is followed by zero or more lowercase letters. The special character * after the closing square bracket specifies to match zero or more occurrences of the character set.

Note: The * only applies to the character set that immediately precedes it, not to the entire regular expression.

A + after the closing square bracket specifies to find one or more occurrences of the character set. You interpret the regular expression " [A-Z]+ " as matching one or more uppercase letters enclosed by spaces. Therefore, this regular expression matches " BIG " and also matches " LARGE ", " HUGE ", " ENORMOUS ", and any other string of uppercase letters surrounded by spaces.


Considerations when using special characters

Since a regular expression followed by an * can match zero instances of the regular expression, it can also match the empty string. For example,

<cfoutput>REReplace("Hello","[T]*","7","ALL") -
#REReplace("Hello","[T]*","7","ALL")#<BR>
</cfoutput>

results in the following output:

REReplace("Hello","[T]*","7","ALL") - 7H7e7l7l7o

The regular expression [T]* can match empty strings. It first matches the empty string before “H” in “Hello”. The “ALL” argument tells REReplace to replace all instances of an expression. The empty string before “e” is matched and so on until the empty string before “o” is matched.

This result might be unexpected. The workarounds for these types of problems are specific to each case. In some cases you can use [T]+, which requires at least one “T”, instead of [T]*. Alternatively, you can specify an additional pattern after [T]*. In the following examples the regular expression has a “W” at the end:

<cfoutput>REReplace("Hello World","[T]*W","7","ALL") –
#REReplace("Hello World","[T]*W","7","ALL")#<BR></cfoutput>

This expression results in the following more predictable output:

REReplace("Hello World","[T]*W","7","ALL") - Hello 7orld

You must be aware of two other consideration when using special characters:

  • If you want to include a hyphen, -, in the square brackets of a character set as a literal character, you cannot escape it as you can other special characters because ColdFusion always interprets a hyphen as a range indicator. Therefore, if you use a literal hyphen in a character set, make it the last character in the set.
  • If you want to include ] (closing square bracket) in the square brackets of a character set it must be the first character. Otherwise, it does not work even if you use \]. The following example shows this:
    • <!--- Want to replace closing square bracket and all a's with * --->
<cfset strSearch = "[Test message]">
<!--- Next line does not work since ] is not the FIRST character
         within [] --->
<cfset re = "[a\]]">
<cfoutput>REReplace(#strSearch#,#re#,"*","ALL") -
      #REReplace(strSearch,re,"*","ALL")#<br>
      Neither ']' nor 'a' was replaced because we searched for 'a'
      followed by ']'<br>
</cfoutput>
<!--- Next line works since ] is the FIRST character within [] --->
<cfset re = "[]a]">
<cfoutput>REReplace(#strSearch#,#re#,"*","ALL") -
      #REReplace(strSearch,re,"*","ALL")#<br>
      Both 'a' and ']' were Replaced with *<br></cfoutput>


Finding repeating characters

In some cases, you may want to find a repeating pattern of characters in a search string. For example, the regular expression "a{2,4}" specifies to match two to four occurrences of “a”. Therefore, it would match: "aa", "aaa", "aaaa", but not "a" or "aaaaa". In the following example, the REFind function returns an index of 6:

<cfset IndexOfOccurrence=REFind("a{2,4}", "hahahaaahaaaahaaaaahhh")>
<!--- The value of IndexOfOccurrence is 6--->

The regular expression "[0-9]{3,}" specifies to match any integer number containing three or more digits: "123", "45678", etc. However, this regular expression does not match a one-digit or two-digit number.

You use the following syntax to find repeating characters:

  • {m,n}

    • Where m is 0 or greater and n is greater than or equal to m. Match m through n (inclusive) occurrences.

    Note that the expression {0,1} is equivalent to the special character ?.

  • {m,}

    • Where m is 0 or greater. Match at least m occurrences. The syntax {,n} is not allowed.

    Note that the expression {1,} is equivalent to the special character +, and {0,} is equivalent to *.

  • {m}

    • Where m is 0 or greater. Match exactly m occurrences.


Case sensitivity in regular expressions

ColdFusion supplies case-sensitive and case-insensitive functions for working with regular expressions. REFind and REReplace perform case-sensitive matching and REFindNoCase and REReplaceNoCase perform case-insensitive matching.

You can build a regular expression that models case-insensitive behavior, even when used with a case-sensitive function. To make a regular expression case insensitive, substitute individual characters with character sets. For example, the regular expression [Jj][Aa][Vv][Aa], when used with the case-sensitive functions REFind or REReplace, matches all of the following string patterns:

  • JAVA
  • java
  • Java
  • jAva
  • All other combinations of case


Using subexpressions

Parentheses group parts of regular expressions together into grouped subexpressions that you can treat as a single unit. For example, the regular expression "ha" specifies to match a single occurrence of the string. The regular expression "(ha)+" matches one or more instances of “ha”.

In the following example, you use the regular expression "B(ha)+" to match the letter "B" followed by one or more occurrences of the string "ha":

<cfset IndexOfOccurrence=REFind("B(ha)+", "hahaBhahahaha")>
<!--- The value of IndexOfOccurrence is 5 --->

You can use the special character | in a subexpression to create a logical "OR". You can use the following regular expression to search for the word "jelly" or "jellies":

<cfset IndexOfOccurrence=REFind("jell(y|ies)", "I like peanut butter and jelly">
<!--- The value of IndexOfOccurrence is 26--->


Using special characters

Regular expressions define the following list of special characters:

+ * ? . [ ^ $ ( ) { | \

In some cases, you use a special character as a literal character. For example, if you want to search for the plus sign in a string, you have to escape the plus sign by preceding it with a backslash:

"\+"

The following table describes the special characters for regular expressions:

Special
Character
Description
\
A backslash followed by any special character matches the literal character itself, that is, the backslash escapes the special character.
For example, "\+" matches the plus sign, and "\\" matches a backslash.
.
A period matches any character, including newline.
To match any character except a newline, use [^#chr(13)##chr(10)#], which excludes the ASCII carriage return and line feed codes. The corresponding escape codes are \r and \n.
[ ]
A one-character character set that matches any of the characters in that set.
For example, "[akm]" matches an “a”, “k”, or “m”. A hyphen in a character set indicates a range of characters; for example, [a-z] matches any single lowercase letter.
If the first character of a character set is the caret (^), the regular expression matches any character except those in the set. It does not match the empty string.
For example, [^akm] matches any character except “a”, “k”, or “m”. The caret loses its special meaning if it is not the first character of the set.
^
If the caret is at the beginning of a regular expression, the matched string must be at the beginning of the string being searched.
For example, the regular expression "^ColdFusion" matches the string "ColdFusion lets you use regular expressions" but not the string "In ColdFusion, you can use regular expressions."
$
If the dollar sign is at the end of a regular expression, the matched string must be at the end of the string being searched.
For example, the regular expression "ColdFusion$" matches the string "I like ColdFusion" but not the string "ColdFusion is fun."
?
A character set or subexpression followed by a question mark matches zero or one occurrences of the character set or subexpression.
For example, xy?z matches either “xyz” or “xz”.
|
The OR character allows a choice between two regular expressions.
For example, jell(y|ies) matches either “jelly” or “jellies”.
+
A character set or subexpression followed by a plus sign matches one or more occurrences of the character set or subexpression.
For example, [a-z]+ matches one or more lowercase characters.
*
A character set or subexpression followed by an asterisk matches zero or more occurrences of the character set or subexpression.
For example, [a-z]* matches zero or more lowercase characters.
()
Parentheses group parts of a regular expression into subexpressions that you can treat as a single unit.
For example, (ha)+ matches one or more instances of “ha”.
(?x)
If at the beginning of a regular expression, specifies to ignore whitespace in the regular expression and lets you use ## for end-of-line comments. You can match a space by escaping it with a backslash.
For example, the following regular expression includes comments, preceded by ##, that are ignored by ColdFusion:
reFind("(?x)
   one                  ##first option
   |two                 ##second option
   |three\ point\ five  ## note escaped spaces
   ", "three point five")
(?m)
If at the beginning of a regular expression, specifies multiline mode for the special characters ^ and $.
When used with ^, the matched string can be at the start of the of entire search string or at the start of new lines, denoted by a linefeed character or chr(10), within the search string. For $, the matched string can be at the end the search string or at the end of new lines.
Note that multiline mode does not recognize a carriage return, or chr(13), as a new line character.
The following example searches for the string "two" across multiple lines:
#reFind("(?m)^two", "one#chr(10)#two")#
This example returns 4 to indicate that it matched "two" after the chr(10) linefeed. Without (?m), the regular expression would not match anything, because ^ only matches the start of the string.
Note that (?m) does not affect \A or \Z, which always match the start or end of the string, respectively. For information on \A and \Z, see Using escape sequences.
(?i)
If at the beginning of a regular expression for REFind(), specifies to perform a case-insensitive compare.
For example, the following line would return an index of 1:
   #reFind("(?i)hi", "HI")#
If you omit the (?i), the line would return an index of zero to signify that it did not find the regular expression.
(?=...)
If at the beginning of a regular expression, specifies to use positive lookahead when searching for the regular expression.
Positive lookahead tests for the parenthesized subexpression like regular parenthesis, but does not include the contents in the match - it merely tests to see if it is there in proximity to the rest of the expression.
For example, consider the expression to extract the protocol from a URL:
<cfset regex = "http(?=://)">
<cfset string = "http://">
<cfset result = reFind(regex, string, 1, "yes")>
mid(string, result.pos[1], result.len[1])
This example results in the string "http". The lookahead parentheses ensure that the "://" is there, but does not include it in the result. If you did not use lookahead, the result would include the extraneous "://".
Lookahead parentheses do not capture text, so backreference numbering will skip over these groups. For more information on backreferencing, see Using backreferences.
(?!...)
If at the beginning of a regular expression, specifies to use negative lookahead. Negative is just like positive lookahead, as specified by (?=...), except that it tests for the absence of a match.
Lookahead parentheses do not capture text, so backreference numbering will skip over these groups. For more information on backreferencing, see Using backreferences.
(?:...)
If you prefix a subexpression with "?:", ColdFusion performs all operations on the subexpression except that it will not capture the corresponding text for use with a back reference.


Using escape sequences

Escape sequences are special characters in regular expressions preceded by a backslash, "\". You typically use escape sequences to represent special characters within a regular expression. For example, the escape sequence "\t" represents a tab character within the regular expression.

For example, the \d escape sequence in a regular expression specifies any digit, similar to [0-9].

The following table lists the escape sequences supported in ColdFusion. Note that escape sequences are case-sensitive.

Escape
Sequence
Description
\b
Specifies a boundary defined by a transition from an alphanumeric character to a nonalphanumeric character, or from a nonalphanumeric character to an alphanumeric character.
For example, the string " Big" contains boundary defined by the space (nonalphanumeric character) and the "B" (alphanumeric character).
The following example uses the \b escape sequence in a regular expression to locate the string "Big" at the end of the search string and not the fragment "big" inside the word "ambiguous".
reFindNoCase("\bBig\b",    "Don’t be ambiguous about Big.")
<!--- The value of IndexOfOccurrence is 26 --->
When used inside of a character set (e.g. [\b]), it specifies a backspace
\B
Specifies a boundary defined by no transition of character type. For example, two alphanumeric character in a row or two nonalphanumeric character in a row; opposite of \b.
\A
Specifies a beginning of string anchor, much like the ^ special character.
However, unlike ^, you cannot combine \A with (?m) to specify the start of newlines in the search string.
\Z
Specifies an end of string anchor, much like the $ special character.
However, unlike $, you cannot combine \Z with (?m) to specify the end of newlines in the search string.
\n
Newline character
\r
Carriage return
\t
Tab
\f
Form feed
\d
Any digit, similar to [0-9]
\D
Any nondigit character, similar to [^0-9]
\w
Any alphanumeric character, similar to [[:alnum:]]
\W
Any nonalphanumeric character, similar to [^[:alnum:]]
\s
Any whitespace character including tab, space, newline, carriage return, and form feed. Similar to [ \t\n\r\f].
\S
Any non-whitespace character, similar to [^ \t\n\r\f]
\xdd
A hexadecimal representation of character, where d is a hexadecimal digit
\ddd
An octal representation of a character, where d is an octal digit, in the form \000 to \377


Using character classes

In character sets within regular expressions, you can include a character class. You enclose the character class inside square brackets, as the following example shows:

REReplace (“Macromedia Web Site”,”[[:space:]]”,”*”,”ALL”)

This code replaces all the spaces with *, producing this string:

Macromedia*Web*Site

You can combine character classes with other expressions within a character set. For example, the regular expression [[:space:]123] searches for a space, 1, 2, or 3. The following example also uses a character class in a regular expression:

<cfset IndexOfOccurrence=REFind("[[:space:]][A-Z]+[[:space:]]", "Some BIG
string")>
<!--- The value of IndexOfOccurrence is 5 --->

The following table shows the character classes that ColdFusion supports:

Character Class | Matches
:alpha: | Matches any letter. Same as [A-Za-z].
:upper: | Matches any uppercase letter, including accented upper-case characters.
:lower: | Matches any lowercase letter, including accented lower-case characters.
:digit: | Matches any digit. Same as [0-9] and \d.
:alnum: | Matches any alphanumeric character. Same as [A-Za-z0-9] or \w.
:xdigit: | Matches any hexadecimal digit. Same as [0-9A-Fa-f].
:blank: | Matches space or a tab.
:space: | Matches space, tab, new line, line feed, or carriage return. Same as \s.
:print: | Matches any printable character.
:punct: | Matches any punctuation character, that is, one of ! ‘ # S % & ` ( ) * + , - . / : ; < = > ? @ [ / ] ^ _ { | } ~
:graph: | Matches any of the characters defined as a printable character except those defined as part of the space character class.
:cntrl: | Matches any character not part of the character classes [:upper:], [:lower:], [:alpha:], [:digit:], [:punct:], [:graph:], [:print:], or [:xdigit:].


Using backreferences

You use parenthesis to group components of a regular expression into subexpressions. For example, the regular expression "(ha)+" matches one or more occurrences of the string "ha".

ColdFusion performs an additional operation when using subexpressions; it automatically saves the characters in the search string matched by a subexpression for later use within the regular expression. Referencing the saved subexpression text is called backreferencing.

You can use backreferencing when searching for repeated words in a string, such as “the the” or “is is”. The following example uses backreferencing to find all repeated words in the search string and replace them with an asterisk:

REReplace("There is is coffee in the the kitchen",
"[ ]+([A-Za-z]+)[ ]+\1"," * ","ALL")

Using this regular expression, ColdFusion detects the two occurrences of "is" as well as the two occurrences of "the", replaces them with an asterisk enclosed in spaces, and returns the following string:

There * coffee in * kitchen

You interpret the regular expression [ ]+([A-Za-z]+)[ ]+\1 as follows:

Use the subexpression ([A-Za-z]+) to search for character strings consisting of one or more letters, enclosed by by one or more spaces, [ ]+, followed by the same character string that matched the first subexpression, \1.

You reference the matched characters of a subexpression using a slash followed by a digit n (\n) where the first subexpression in a regular expression is referenced as \1, the second as \2, etc. The next section includes an example using multiple backreferences.


Using backreferences in replacement strings

You can use backreferences in the replacement string of both the REReplace and REReplaceNoCase functions. For example, to replace the first repeated word in a text string with a single word, use the following syntax:

REReplace("There is is a cat in in the kitchen",
"([A-Za-z]+)[ ]+\1","\1")

This results in the sentence:

“There is a cat in in the kitchen”

You can use the optional fourth parameter to REReplace, scope, to replace all repeated words, as in the following code:

REReplace("There is is a cat in in the kitchen",
"([A-Za-z]+)[ ]+\1","\1","ALL")

This results in the following string:

“There is a cat in the kitchen”

The next example uses two backreferences to reverse the order of the words "apples" and "pairs" in a sentence:

<cfset astring = "apples and pears, apples and pears, apples and pears">
<cfset newString = REReplace("#astring#", "(apples) and (pears)",
"\2 and \1","ALL")>

In this example, you reference the subexpression (apples) as \1 and the subexpression (pears) as \2. The REReplace function returns the string:

"pears and apples, pears and apples, pears and apples"

Note: To use backreferences in either the search string or the replace string, you must use parentheses within the regular expression to create the corresponding subexpression. Otherwise, ColdFusion throws an exception.


Using backreferences to perform case conversions in replacement strings

The REReplace and REReplaceNoCase functions support special characters in replacement strings to convert replacement characters to uppercase or lowercase. The following table describes these special characters:

Special Character | Description
\u | Convert the next character to uppercase
\l | Convert the next character to lowercase
\U | Convert all characters to uppercase until encountering \E
\L | Convert all characters to lowercase until encountering \E
\E | End \U or \L

To include a literal \u, or other code, in a replacement string, escape it with another backslash; for example \\u .

For example, the following statement replaces the uppercase string "HELLO" with a lowercase "hello". Note that this example uses backreferences to perform the replacement. For more information on using backreferences, see Using backreferences in replacement strings.

reReplace("HELLO", "([[:upper:]]*)", "Don't shout\scream \L\1")

The result of this example is the string "Don't shout\scream hello".


Escaping special characters in replacement strings

You use the backslash character, \, to escape backreference and case-conversion characters in replacement strings. For example, to include a literal "\u" in a replacement string, escape it as in "\\u".


Omitting subexpressions from backreferences

By default, a set of parentheses will both group the subexpression and capture its matched text for later referral by backreferences. However, if you insert "?:" as the first characters of the subexpression, ColdFusion performs all operations on the subexpression except that it will not capture the corresponding text for use with a back reference.

This is useful when alternating over subexpressions containing differing numbers of groups would complicate backreference numbering. For example, consider an expression to insert a "Mr." in between Bonjour|Hi|Hello and Bond, using a nested group for alternating between Hi & Hello:

<cfset regex = "(Bonjour|H(?:i|ello))( Bond)">
<cfset replaceString = "\1 Mr.\2">
<cfset string = "Hello Bond">
#reReplace(string, regex, replaceString)#

This example returns "Hello Mr. Bond". If you did not prohibit the capturing of the Hi/Hello group, the \2 backreference would end up referring to that group instead of " Bond", and the result would be "Hello Mr.ello".


Returning matched subexpressions

The REFind and REFindNoCase functions return the location in the search string of the first match of the regular expression. Even though the search string in the next example contains two matches of the regular expression, the function only returns the index of the first:

<cfset IndexOfOccurrence=REFind(" BIG ", "Some BIG BIG string")>
<!--- The value of IndexOfOccurrence is 5 --->

To find all instances of the regular expression, you must call the REFind and REFindNoCase functions multiple times.

Both the REFind and REFindNoCase functions take an optional third parameter that specifies the starting index in the search string for the search. By default, the starting location is index 1, the beginning of the string.

To find the second instance of the regular expression in this example, you call REFind with a starting index of 8:

<cfset IndexOfOccurrence=REFind(" BIG ", "Some BIG BIG string", 8)>
<!--- The value of IndexOfOccurrence is 9 --->

In this case, the function returns an index of 9, the starting index of the second string " BIG ".

To find the second occurrence of the string, you must know that the first string occurred at index 5 and that the string’s length was 5. However, REFind only returns starting index of the string, not its length. So, you either must know the length of the matched string to call REFind the second time, or you must use subexpressions in the regular expression.

The REFind and REFindNoCase functions allow you to get information about matched subexpressions. If you set these functions’ fourth parameter, ReturnSubExpression, to True, the functions return a CFML structure with two arrays, pos and len, containing the positions and lengths of text strings that match the subexpressions of a regular expression, as the following example shows:

<cfset sLenPos=REFind(" BIG ", "Some BIG BIG string", 1, "True")>
<cfoutput>
   <cfdump var="#sLenPos#">
</cfoutput><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

Element one of the pos array contains the starting index in the search string of the string that matched the regular expression. Element one of the len array contains length of the matched string. For this example, the index of the first " BIG " string is 5 and its length is also 5. If there are no occurrences of the regular expression, the pos and len arrays each contain one element with a value of 0.

You can use the returned information with other string functions, such as mid. The following example returns that part of the search string matching the regular expression:

<cfset myString="Some BIG BIG string">
<cfset sLenPos=REFind(" BIG ", myString, 1, "True")>
<cfoutput>
   #mid(myString, sLenPos.pos[1], sLenPos.len[1])#
</cfoutput>

Each additional element in the pos array contains the position of the first match of each subexpression in the search string. Each additional element in len contains the length of the subexpression’s match.

In the previous example, the regular expression " BIG " contained no subexpressions. Therefore, each array in the structure returned by REFind contains a single element.

After executing the previous example, you can call REFind a second time to find the second occurrence of the regular expression. This time, you use the information returned by the first call to make the second:

<cfset newstart = sLenPos.pos[1] + sLenPos.len[1] - 1>
<!--- subtract 1 because you need to start at the first space --->
<cfset sLenPos2=REFind(" BIG ", "Some BIG BIG string", newstart, "True")>
<cfoutput>
   <cfdump var="#sLenPos2#">
</cfoutput><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

If you include subexpressions in your regular expression, each element of pos and len after element one contains the position and length of the first occurrence of each subexpression in the search string.

In the following example, the expression [A-Za-z]+ is a subexpression of a regular expression. The first match for the expression ([A-Za-z]+)[ ]+, is “is is”.

<cfset sLenPos=REFind("([A-Za-z]+)[ ]+\1",
"There is is a cat in in the kitchen", 1, "True")>
<cfoutput>
   <cfdump var="#sLenPos#">
</cfoutput><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

The entries sLenPos.pos[1] and sLenPos.len[1] contain information about the match of the entire regular expression. The array elements sLenPos.pos[2] and sLenPos.len[2] contain information about the first subexpression (“is”). Because REFind returns information on the first regular expression match only, the sLenPos structure does not contain information about the second match to the regular expression, "in in".

The regular expression in the following example uses two subexpressions. Therefore, each array in the output structure contains the position and length of the first match of the entire regular expression, the first match of the first subexpression, and the first match of the second subexpression.

<cfset sString = "apples and pears, apples and pears, apples and pears">
<cfset regex = "(apples) and (pears)">
<cfset sLenPos = REFind(regex, sString, 1, "True")>
<cfoutput>
   <cfdump var="#sLenPos#">
</cfoutput><br><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

For a full discussion of subexpression usage, see the sections on REFind and REFindNoCase in the ColdFusion Functions chapter in the CFML Reference.


Specifying minimal matching

The regular expression quantifiers ?, *, +, {min,} and {min,max} specify a minimum and/or maximum number of instances of a given expression to match. By default, ColdFusion locates the greatest number characters in the search string that match the regular expression. This behavior is called maximal matching.

For example, you use the regular expression "<b>(.*)</b>" to search the string "<b>one</b> <b>two</b>". The regular expression "<b>(.*)</b>", matches both of the following:

  • <b>one</b>
  • <b>one</b> <b>two</b>

By default, ColdFusion always tries to match the regular expression to the largest string in the search string. The following code shows the results of this example:

<cfset sLenPos=REFind("<b>(.*)</b>", "<b>one</b> <b>two</b>", 1, "True")>
<cfoutput>
   <cfdump var="#sLenPos#">
</cfoutput><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

As you can see, the starting position of the string is 1 and its length is 21, which corresponds to the largest of the two possible matches.

However, in some case you may want to override this default behavior to find the shortest string that matches the regular expression. ColdFusion includes minimal-matching quantifiers that allow you to specify to match on the smallest string. The following table describes these expressions:

Expression | Description
*? | minimal-matching version of *
+? | minimal-matching version of +
?? | minimal-matching version of ?
{min,}? | minimal-matching version of {min,}
{min,max}? | minimal-matching version of {min,max}
{n}? | (no different from {n}, supported for notational consistency)

Modifying the previous example to use the minimal-matching syntax becomes:

<cfset sLenPos=REFind("<b>(.*?)</b>", "<b>one</b> <b>two</b>", 1, "True")>
<cfoutput>
   <cfdump var="#sLenPos#">
</cfoutput><br>

The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

As you can see, the length of the string found by the regular expression is 10, corresponding to the string "<b>one</b>".


Regular expression examples

The following examples show some regular expressions and describe what they match:

Expression
Description
[\?&]value=
A URL parameter value in a URL.
[A-Z]:(\\[A-Z0-9_]+)+
An uppercase DOS/Windows path in which (a) is not the root of a drive, and (b) has only letters, numbers, and underscores in its text.
[A-Za-z][A-Za-z0-9_]*
A ColdFusion variable with no qualifier.
([A-Za-z][A-Za-z0-9_]*)(\.[A-Za-z][A-Za-z0-9_]*)?
A ColdFusion variable with no more than one qualifier; for example, Form.VarName, but not Form.Image.VarName.
(\+|-)?[1-9][0-9]*
An integer that does not begin with a zero and has an optional sign.
(\+|-)?[1-9][0-9]*(\.[0-9]*)?
A real number.
(\+|-)?[1-9]\.[0-9]*E(\+|-)?[0-9]+
A real number in engineering notation.
a{2,4}
Two to four occurrences of “a”: aa, aaa, aaaa.
(ba){3,}
At least three “ba” pairs: bababa, babababa, and so on.


Regular expressions in CFML

The following examples of CFML show some common uses of regular expression functions:

Expression
Returns
REReplace (CGI.Query_String, "CFID=[0-9]+[&]*", "")
The query string with parameter CFID and its numeric value stripped out.
REReplace(“I Love Jellies”, ”[[:lower:]]”,”x”,”ALL”
I Lxxx Jxxxxxx
REReplaceNoCase(“cabaret”,”[A-Z]”, ”G”,”ALL”)
GGGGGGG
REReplace (Report,"\$[0-9,]*\.[0-9]*","$***.**")", "")
The string value of the variable Report with all positive numbers in the dollar format changed to "$***.**".
REFind ("[Uu]\.?[Ss]\.?[Aa}\.?", Report )
The position in the variable Report of the first occurrence of the abbreviation USA. The letters can be in either case and the abbreviation can have a period after any letter.
REFindNoCase("a+c","ABCAACCDD")
4
REReplace("There is is coffee in the the kitchen",
"([A-Za-z]+)[ ]+\1","*","ALL")
There * coffee in * kitchen
REReplace(report, "<[^>]*>", "", "All")
Removes all HTML tags from a string value of the report variable.


Types of regular expression technologies

Many types of regular expression technologies are available to programmers. JavaScript, Perl, and POSIX are all examples of different regular expression technologies. Each technology has its own syntax specifications and is not necessarily compatible with other technologies.

ColdFusion supports regular expressions that are Perl compliant with a few exceptions:

  • A period, ., always matches newlines
  • In replacement strings, use \n instead of $n for backreference variables. ColdFusion escapes all $ in the replacement string.
  • You do not have to escape backslashes in replacement strings. ColdFusion escapes them, with the exception of case conversion sequences or escaped versions (e.g. \u or \\u).
  • Embedded modifiers ( (?i), etc. ) always affect the entire expression, even if they are inside a group.
  • \Q and the combinations \u\L and \l\U are not supported in replacement strings.

The following Perl statements are not supported:

  • Lookbehind (?<=) (<?!)
  • \x{hhhh}
  • \N
  • \p
  • \C

An excellent reference on regular expressions is Mastering Regular Expressions, Jeffrey E. F. Friedl. O'Reilly & Associates, Inc., 1997. ISBN: 1-56592-257-3, .

Previous


Reusing Code in ColdFusion Pages

This chapter describes techniques for reusing code in ColdFusion pages. These techniques let you write your code once and use it, without copying it, in many places. This chapter describes the techniques and their features, and provides advice on selecting among the techniques.

Contents
  • About reusable CFML elements
  • Including pages with the cfinclude tag
  • Calling user-defined functions
  • Using custom CFML tags
  • Using CFX tags
  • Using ColdFusion Components
  • Selecting among ColdFusion code reuse methods
Next


About reusable CFML elements

ColdFusion provides you with several types of reusable elements, sections of code that you can create once and use multiple times in an application. Many of these elements also let you extend the built-in capabilities of ColdFusion. ColdFusion provides the following reusable CFML elements:

  • ColdFusion pages you include using the cfinclude tag
  • User-defined functions (UDFs)
  • Custom CFML tags
  • CFX (ColdFusion Extension) tags
  • ColdFusion components

The following sections describe the features of each of these elements and provide guidelines for determining which of these tools to use in your application. Other chapters describe the tools in detail. The last section in this chapter includes a table that helps you chose among these techniques for different purposes.

ColdFusion can also use elements developed using other technologies, including the following:

  • JSP tags from JSP tag libraries
  • Java objects, including objects in the Java runtime environment and JavaBeans
  • Microsoft COM (Component Object Model) objects
  • CORBA (Common Object Request Broker Architecture) objects
  • Web services

This chapter does not discuss these elements or their use. For information on using JSP tags and Java objects, see Integrating J2EE and Java Elements in CFML Applications. For information on using COM and CORBA objects, see Integrating COM and CORBA Objects in CFML Applications. For information on using web services, see Using Web Services


Including pages with the cfinclude tag

The cfinclude tag adds the contents of a ColdFusion page to another ColdFusion page, as if the code on the included page were part of the page that uses the cfinclude tag. It lets you pursue a “write once use multiple times” strategy for ColdFusion elements that you incorporate in multiple pages. Instead of copying and maintaining the same code on multiple pages, you can store the code in one page and then refer to it in many pages. For example, the cfinclude tag is commonly used to put a header and footer on multiple pages. This way, if you change the header or footer design, you only change the contents of a single file.

The model of an included page is that it is part of your page; it just resides in a separate file. The cfinclude tag cannot pass parameters to the included page, but the included page has access to all the variables on the page that includes it. The following figure shows this model:

This is a picture of the feature being described.


Using the cfinclude tag

When you use the cfinclude tag to include one ColdFusion page in another ColdFusion page, the page that includes another page is referred to as the calling page. When ColdFusion encounters a cfinclude tag it replaces the tag on the calling page with the output from processing the included page. The included page can also set variables in the calling page.

The following line shows a sample cfinclude tag:

<cfinclude template = "header.cfm">

ColdFusion searches for included files as follows:

  • The template attribute specifies a path relative to the directory of the calling page.
  • If the template value is prefixed with a forward slash (/), ColdFusion searches for the included file in directories that you specify on the Mappings page of the ColdFusion Administrator.

Note: You cannot break CFML code blocks across pages. For example, if you open a cfoutput block in a ColdFusion page, you must close the block on the same page; you cannot include the closing portion of the block in an included page.

Caution:A page must not include itself. Doing so causes an infinite processing loop, and you must stop the ColdFusion Server to resolve the problem.

To include code in a calling page:

  1. Create a ColdFusion page named header.cfm that displays your company’s logo. Your page can consist of just the following lines, or it can include many lines to define an entire header:
    2. <img src="mylogo.gif">
<br>

(For this code to work, you must also put your company’s logo as a GIF file in the same directory as the header.cfm file.)
  2. Create a ColdFusion page with the following content:
    3. <html>
<head>
   <title>Test for Include</title>
</head>
<body>
   <cfinclude template="header.cfm">
</body>
</html>
  3. Save the file as includeheader.cfm and view it in a browser.

The header should appear along with the logo.


Recommended uses

Consider using the cfinclude tag in the following cases:

  • For page headers and footers
  • To divide a large page into multiple logical chunks that are easier to understand and manage
  • For large “snippets” of code that are used in many places but do not require parameters or fit into the model of a function or tag


Calling user-defined functions

User-defined functions (UDFs) let you create application elements in a format in which you pass in arguments and get a return a value. You can define UDFs using CFScript or the cffunction tag. The two techniques have several differences, of which the following is most important:

  • If you use the cffunction tag, your function can include CFML tags.
  • If you write your function using CFScript, you cannot include CFML tags.

You use UDFs in your application pages as you use standard ColdFusion functions. You can create a function for an algorithm or procedure that you use frequently, and then use the function wherever you need the procedure.

As with custom tags, you can easily distribute UDFs to others. For example, the Common Function Library Project at http://www.cflib.org is an open-source collection of CFML user-defined functions.


Calling UDFs

To call a UDF, use it as you would a ColdFusion built-in function. For example, the following line calls the function MyFunct and passes it two arguments:

<cfset returnValue=MyFunct(Arg1, Arg2)>


Recommended uses

Typical uses of UDFs include, but are not limited to, the following:

  • Data manipulation routines, such as a function to reverse an array
  • String and date and time routines, such as a function to determine whether a string is a valid IP address
  • Mathematical calculation routines, including standard trigonometric and statistical operations or calculating loan amortization
  • Routines that call functions externally, for example using COM or CORBA, such as routines to determine the space available on a Windows file system drive

Consider using UDFs under the following circumstances:

  • You have to pass in a number of arguments, process the results, and return a value. UDFs can return complex values, including structures that contain multiple simple values.
  • You want to provide logical units such as data manipulation functions.
  • Your code must be recursive.
  • You distribute your code to others.

If you can create either a UDF or a custom CFML tag for a particular purpose, first consider creating a UDF, because invoking it requires less system overhead than using a custom tag.


For more information

For more information on user-defined functions, see Writing and Calling User-Defined Functions.


Using custom CFML tags

Custom tags written in CFML behave like ColdFusion tags. They can do all of the following:

  • Take arguments.
  • Have tag bodies with beginning and ending tags.
  • Can do specific processing when ColdFusion encounters the beginning tag.
  • Can do processing that is different from the begging tag processing when ColdFusion encounters the ending tag.
  • Have any valid ColdFusion page content in their bodies, including both ColdFusion built-in tags and custom tags (referred to as nested tags), or even JSP tags or JavaScript.
  • Be called recursively; that is, a custom tag can, if designed properly, call itself in the tag body.
  • Return values to the calling page in a common scope or the calling page’s Variables scope, but custom tags do not return values directly, the way functions do.

Although a custom tag and a ColdFusion page that you include using the cfinclude tag are both ColdFusion pages, they differ in how they are processed. When a page calls a custom tag, it hands processing off to the custom tag page and waits until the custom tag page completes. When the custom tag finishes, it returns processing (and possibly data) to the calling page; the calling page can then complete its processing. The following figure shows how this works. The arrows indicate the flow of ColdFusion processing the pages.

This is a picture of the feature being described.


Calling custom CFML tags

Unlike built-in tags, you can invoke custom CFML tags in the following three ways:

  • Call a tag directly.
  • Call a tag using the cfmodule tag.
  • Use the cfimport tag to import a custom tag library directory.

To call a CFML custom tag directly, precede the file name with cf_, omit the .cfm extension, and put the name in angle brackets (<>). For example, use the following line to call the custom tag defined by the file mytag.cfm:

<cf_myTag>

If your tag takes a body, end it with the same tag name preceded with a forward slash (/), as follows:

</cf_myTag>

For information on using the cfmodule and cfimport tags to call custom CFML tags, see Creating and Using Custom CFML Tags.


Recommended uses

ColdFusion custom tags let you abstract complex code and programming logic into simple units. These tags let you maintain a CFML-like design scheme for your code. You can easily distribute your custom tags and share tags with others. For example, the Macromedia ColdFusion Developer’s Exchange includes a library of custom tags that perform a wide variety of often-complex jobs; see http://devex.macromedia.com/developer/gallery/index.cfm.

Consider using CFML custom tags in the following circumstances:

  • You need a tag-like structure, which has a body and an end tag, with the body contents changing from invocation to invocation.
  • You want to associate specific processing with the beginning tag, the ending tag, or both tags.
  • To use a logical structure in which the tag body uses “child” tags or subtags. This structure is similar to the cfform tag, which uses subtags for the individual form fields.
  • You do not need a function format in which the calling code uses a direct return value.
  • Your code must be recursive.
  • Your functionality is complex.
  • To distribute your code in a convenient form to others.

If you can create either a UDF or a custom CFML tag for a purpose, first consider creating a UDF, because invoking it requires less system overhead than using a custom tag.


For more information

For more information on custom CFML tags, see Creating and Using Custom CFML Tags.


Using CFX tags

ColdFusion Extension (CFX) tags are custom tags that you write in Java or C++. Generally, you create a CFX tag to do something that is not possible in CFML. CFX tags also let you use existing Java or C++ code in your ColdFusion application. Unlike CFML custom tags, CFX tags cannot have bodies or ending tags.

CFX tags can return information to the calling page in a page variable or by writing text to the calling page.

CFX tags can do the following:

  • Have any number of custom attributes.
  • Create and manipulate ColdFusion queries.
  • Dynamically generate HTML to be returned to the client.
  • Set variables within the ColdFusion page from which they are called.
  • Throw exceptions that result in standard ColdFusion error messages.


Calling CFX tags

To use a CFX tag, precede the class name with cfx_ and put the name in angle brackets. For example, use the following line to call the CFX tag defined by the MyCFXClass class and pass it one attribute.

<cfx_MyCFXClass myArgument="arg1">


Recommended uses

CFX tags provide one way of using C++ or Java code. However, you can also create Java classes and COM objects and access them using the cfobject tag. CFX tags, however, provide some built-in features that the cfobject tag does not have:

  • CFX tags are easier to call in CFML code. You use CFX tags directly in CFML code as you would any other tag, and you can pass arguments using a standard tag format.
  • ColdFusion provides predefined classes for use in your Java or C++ code that facilitate CFX tag development. These classes include support for request handling, error reporting, and query management.

You should consider using CFX tags in the following circumstances:

  • You already have existing application functionality written in C++ or Java that you want to incorporate into your ColdFusion application.
  • You cannot build the functionality you need using ColdFusion elements.
  • You want to provide the new functionality in a tag format, as opposed to using the cfobject tag to import native Java or COM objects.
  • You want use the Java and C++ classes provided by ColdFusion for developing your CFX code.


For more information

For more information on CFX tags, see Building Custom CFXAPI Tags.


Using ColdFusion Components

Unlike other Coldfusion reusable elements, ColdFusion components encapsulate multiple, related, functions. A ColdFusion component is essentially a set of related UDFs and variables, with additional functionality to provide and control access to the component contents. ColdFusion components can make their data private, so that it is available to all functions (also called methods) in the component, but not to any application that uses the component.

ColdFusion components have the following features:

  • They are designed to provide related services in a single unit.
  • They can provide web services and make them available over the internet.
  • They can provide ColdFusion services that Flash clients can call directly.
  • They have several features that are familiar to object-oriented programmers including data hiding, inheritance, packages, and introspection.


Creating and using ColdFusion components

Creating and using a component is more complex than creating and using a UDF. For example, you specify a component and one or more functions. You can invoke ColdFusion components in many ways, including using the cfinvoke and cfobject tags. You can also use forms, URLs, and the Flash client-side action script.

To invoke a component method with a cfinvoke tag, use code such as the following:

<cfinvoke component="componentName" method="methodName"
returnVariable="variableName" argumentCollection="argumentStruct">


Recommended uses

Consider using ColdFusion components when doing the following:

  • Creating web services. (To create web services in ColdFusion, you must use components.)
  • Creating services that are callable by Flash clients.
  • Creating libraries of related functions, particularly if they must share data.
  • Using integrated application security mechanisms based on roles and the requestor location.
  • Developing code in an object-oriented manner, in which you use methods on objects and can create objects that extend the features of existing objects.


For more information

For more information on using ColdFusion Components, see Building and Using ColdFusion Components.


Selecting among ColdFusion code reuse methods

The following table lists common reasons to employ code reuse methods and indicates the techniques to consider for each purpose. The letter P indicates that the method is preferred. (There can be more than one preferred method.) The letter A means that the method provides an alternative that might be useful in some circumstances.

This table does not include CFX tags. You use CFX tags only when you should code your functionality in C++ or Java. For more information about using CFX tags, see Using CFX tags.

Purpose | cfinclude tag | Custom tag | UDF | Component
Provide code, including CFML, HTML, and static text, that must be used in multiple pages. | P |  |  |
Deploy headers and footers. | P |  |  |
Include one page in another page. | P |  |  |
Divide pages into smaller units. | P |  |  |
Use variables from a calling page. | A | P | P |
Implement code that uses recursion. |  | P | P | P
Distribute your code to others. |  | P | P | P
Operate on a body of HTML or CFML text. |  | P |  |
Use subtags. |  | P |  |
Provide a computation, data manipulation, or other procedure. |  | A | P |
Provide a single functional element that takes any number of input values and returns a (possibly complex) result. |  | A | P |
Use variables, whose variable names might change from use to use. |  | A | P | P
Provide accessibility from Flash clients. |  | A | A | P
Use built-in user security features. |  |  | A | P
Encapsulate multiple related functions and properties. |  |  |  | P
Create web services |  |  |  | P
Implement object-oriented coding methodologies. |  |  |  | P
Previous


Writing and Calling User-Defined Functions

This chapter describes how to create and call user-defined functions (UDFs).

Contents
  • About user-defined Functions
  • Calling user-defined functions
  • Creating user-defined functions
  • Calling functions and using variables
  • A User-defined Function Example
  • Using UDFs Effectively
Next


About user-defined Functions

You can create user-defined functions, or UDFs (also known as custom functions), and use them in your application pages as you do standard ColdFusion functions. This allows you to create a function for an algorithm or procedure that you use frequently, and then use the function wherever you need the procedure. If you must change the procedure, you change only one piece of code. You can use your function anywhere that you can use a ColdFusion expression: in tag attributes, between pound (#) signs in output, and in CFScript code. Typical uses of UDFs include, but are not limited to the following:

  • Data manipulation routines, such as a function to reverse an array
  • String and date/time routines, such as a function to determine whether a string is a valid IP address
  • Mathematical calculation routines, including standard trigonometric and statistical operations or calculating loan amortization
  • Routines that call functions externally, for example using COM or CORBA, including routines to determine the space available on a Windows file system drive

For information about selecting among User-defined functions, custom tags, and ColdFusion components, see Reusing Code in ColdFusion Pages.

Note: The Common Function Library Project at http://www.cflib.org is an open source collection of CFML user-defined functions.

To use a user-defined function, you define the function and then call it.

You typically define the function on your ColdFusion page or a page that you include. You can also define the function on one page and put it in a scope that is shared with the page that calls it. (For more information on UDF scoping, see Specifying the scope of a function.) You can also put commonly-used functions on a single CFML page and include it in your Application.cfm page.


Calling user-defined functions

You can call a UDF in two ways:

  • With unnamed, positional arguments, as you would call a built-in function
  • With named arguments, as you would use attributes in a tag

You can use either technique for any function. However, if you use named arguments, you must use the same argument names to call the function as you use to define the function. You cannot call a function with a mixture of named and unnamed arguments. For more information on calling functions with and without argument names, see Calling functions and using variables.

One example of a user-defined function is a TotalInterest function that calculates loan payments based on a principal amount, annual percentage, and loan duration in months. (See A User-defined Function Example for this function’s definition.) You might call the function without argument names on a form’s action page as follows:

<cfoutput>
Interest: #TotalInterest(Form.Principal, Form.Percent, Form.Months)#
</cfoutput>

You might call the function with argument names as follows:

<cfoutput>
Interest: #TotalInterest(principal=Form.Principal, annualPercent=Form.Percent,
      months=Form.Months)#
</cfoutput>


Creating user-defined functions

You can use tags or CFScript to create a UDF. Each technique has advantages and disadvantages.


Creating functions using CFScript

You use the function statement to define the function in CFScript. CFScript function definitions have the following features and limitations:

  • The function definition syntax is familiar to anyone who uses JavaScript or most programming languages.
  • CFScript is efficient for writing business logic, such as expressions and conditional operations.
  • CFScript function definitions cannot include CFML tags.

The following is a CFScript definition for a function that returns a power of 2:

<cfscript>
function twoPower(exponent)
{
      return 2^exponent;
}
</cfscript>

For more information on how to use CFScript to define a function, see Defining functions in CFScript.


Creating functions using tags

You use the cffunction tag to define a UDF in CFML. The cffunction tag syntax has the following features and limitations:

  • Developers who have a background in CFML or HTML, but no scripting or programming experience will be more familiar with the syntax.
  • You can include any ColdFusion tag in your function definition. Therefore, you can create a function, for example, that accesses a database.
  • You can embed CFScript code inside the function definition.
  • The cffunction tag provides attributes that enable you to easily limit the execution of the tag to authorized users or specify how the function can be accessed.

The following code uses the cffunction tag to define the exponentiation function:

<cffunction name="twoPower" output=True>
   <cfargument name="exponent">
   <cfreturn 2^exponent>
</cffunction>

For more information on how to use the cffunction tag to define a function, see Defining functions using the cffunction tag.


Rules for function definitions

The following rules apply to functions that you define using CFScript or the cffunction tag:

  • The function name must be unique. It must be different from any existing variable, UDF, or built-in function name.
  • The function name must not start with the letters “cf” in any form. (For example, CF_MyFunction cfmyFunction, and cfxMyFunction are not valid UDF names.)
  • You cannot redefine or overload a function. If a function definition is active, ColdFusion generates an error if you define a second function with the same name.
  • You cannot nest function definitions. That is, you cannot define one function inside another function definition.
  • The function can be recursive, that is, the function definition body can call the function.
  • The function does not have to return a value.

You can define a function in the following places:

  • On the page where it is called. You can even define it below the place on the page where it is called, but this poor coding practice can result in confusing code.
  • On a page that you include using a cfinclude tag. The cfinclude tag must be executed before the function gets called. For example, you can define all your application’s functions on a single page and place a cfinclude tag at the top of pages that use the functions.
  • On any page that puts the function name in a scope common with the page on which you call the function.
  • On the Application.cfm page.

For recommendations on selecting where you define functions, see the sections Using Application.cfm and function include files and Specifying the scope of a function.


About the Arguments scope

All function arguments exist in their own scope, the Arguments scope.

The Arguments scope exists for the life of a function call. When the function returns, the scope and its variables is destroyed.

However, destroying the Argument scope does not destroy variables, such as structures or query objects, that ColdFusion passes to the function by reference. The variables on the calling page that you use as function arguments continue to exist; if the function changes the argument value, the variable in the calling page reflects the changed value.

The Arguments scope is special, in that you can treat the scope as either an array or a structure. This dual nature of the Arguments scope is useful because it makes it easy to use arguments in any of the following circumstances:

  • You define the function using CFScript’
  • You define the function using the cffunction tag
  • You pass arguments using argument name=value format
  • You pass arguments as values only.
  • The function takes optional, undeclared arguments.

The following sections describe the general rules for using the Arguments scope as an array and a structure. For more information on using the Arguments scope in functions defined using CFScript, see Using the Arguments scope in CFScript. For more information on using the Arguments scope in functions defined using the cffunction tag, see Using the Arguments scope in cffunction definitions


The contents of the Arguments scope

The following rules apply to the Arguments scope and its contents:

  • The scope contains all the arguments passed into a function.
  • If you use cffunction to define the function, the scope always contains an entry "slot" for each declared argument, even if you do not pass the argument to the function when you call it. If you do not pass a declared (optional) argument, the scope entry for that argument is empty.

    • When you call a function that you defined using CFScript you must pass the function a value for each argument declared in the function definition. Therefore, the Arguments scope for a CFScript call does not have empty slots.

The following example illustrates these rules. Assume that you have a function declared as follows:

<cffunction name="TestFunction">
   <cfargument name="Arg1" >
   <cfargument name="Arg2">
</cffunction>

You can call this function with a single argument, as in the following line:

<cfset TestFunction(1)>

The resulting Arguments scope looks as follows:

As an array |  | As a structure |
Entry | Value | Entry | Value
1 | 1 | Arg1 | 1
2 | undefined | Arg2 | undefined

In this example, the following functions return the value 2, because there are two defined arguments:

ArrayLen(Arguments)
StructCount(Arguments)

However, the following tests return the value False, because the contents of the second element in the Arguments scope is undefined.

Isdefined("Arguments.Arg2")
testArg2 = Arguments[2]>
Isdefined("testArg2")

Note: The IsDefined function does not test the existence of array elements. To test whether an array index contains data, copy the array element to a simple variable and use the IsDefined function to test the existence of the copy.


Using the Arguments scope as an array

The following rules apply to referencing Arguments scope as an array:

  • If you call the function using unnamed arguments, the array index is the position of the argument in the function call.
  • If you use names to pass the arguments, the array indexes correspond to the order in which the arguments are declared in the function definition.
  • If you use names to pass arguments, and do not pass all the arguments defined in the function, the Arguments array has an empty entry at the index corresponding to the argument that was not passed. This rule applies only to functions created using the cffunction tag.
  • If you use a name to pass an optional argument that is not declared in the function definition, the array index of the argument is the sum of the following:
    1. The number of arguments defined with names in the function.
    2. The position of the optional argument among the arguments passed in that do not have names defined in the function.

      3. However, using argument names in this manner is not good programming practice because you cannot ensure that you always use the same optional argument names when calling the function.

To demonstrate these rules, define a simple function that displays the contents of its Arguments array and call the function with various argument combinations, as shown in the following example:

<cffunction name="TestFunction" >
   <cfargument name="Arg1">
   <cfargument name="Arg2">
   <cfloop index="i" from="1" to="#ArrayLen(Arguments)#">
      <cfoutput>Argument #i#: #Arguments[i]#<br></cfoutput>
   </cfloop>
</cffunction>

<strong>One Unnamed argument</strong><br>
<cfset TestFunction(1)>
<strong>Two Unnamed arguments</strong><br>
<cfset TestFunction(1, 2)>
<strong>Three Unnamed arguments</strong><br>
<cfset TestFunction(1, 2, 3)>
<strong>Arg1:</strong><br>
<cfset TestFunction(Arg1=8)>
<strong>Arg2:</strong><br>
<cfset TestFunction(Arg2=9)>
<strong>Arg1=8, Arg2=9:</strong><br>
<cfset TestFunction(Arg1=8, Arg2=9)>
<strong>Arg2=6, Arg1=7</strong><br>
<cfset TestFunction(Arg2=6, Arg1=7)>
<strong>Arg1=8, Arg2=9, Arg3=10:</strong><br>
<cfset TestFunction(Arg1=8, Arg2=9, Arg3=10)>
<strong>Arg2=6, Arg3=99, Arg1=7</strong><br>
<cfset TestFunction(Arg2=6, Arg3=99, Arg1=7)>

Note: Although you can use the Arguments scope as an array, the IsArray(Arguments) function always returns false and the cfdump tag displays the scope as a structure.


Using the Arguments scope as a structure

The following rule applies when referencing Arguments scope as a structure:

  • Use the argument names as structure keys. For example, if your function definition includes a Principal argument, refer to the argument as Arguments.Principal.

The following rules are also true, but avoid writing code that uses them. To ensure program clarity, only use the Arguments structure for arguments that you name in the function definition. Use the Arguments scope as an array for optional arguments that you do not declare in the function definition.

  • If the function can take unnamed optional arguments, use an index number as the key to reference the argument in the structure. For example, if the function declaration includes two named arguments and you call the function with three arguments, refer to the third argument as Arguments.3.

    • Note: The IsDefined function always returns false when you reference an unnamed optional arguments using structure notation. For example, IsDefined(Arguments.3) for the function described in the preceding paragraph always returns false.

  • If you do not name an optional argument in the function definition, but do use a name for it in the function call, use the name specified in the function call For example, if you have an unnamed optional argument and call the function using the name myOptArg for the argument, you can refer to the argument as Arguments.myOptArg in the function body. This usage, however, is poor programming practice, as it makes the function definition contents depend on variable names in the code that calls the function.


Function-only variables and the This scope

In addition to the Arguments scope, each function can has a number of variables that exist only inside the function, and are not saved between times the function gets called. As soon as the function exits, all the variables in this scope are removed.

In CFScript, you create function-only variables with the var statement. Unlike other variables, you never prefix function-only variables with a scope name.

In functions defined using the cffunction tag, you create function-only variables by putting them in the This scope. You must always use the scope prefix, This, when you refer to these variables. For more information on using the This scope, see Function-only variables and the This scope.

For more information on using function-only variables in general, see Using function-only and This scope variables.


Good argument naming practice

An argument’s name should represent its use. For example, the following code is unlikely to result in confusion:

<cfscript>
   function SumN(Addend1,Addend2)
   { return Addend1 + Addend2; }
</cfscript>
<cfset x = 10>
<cfset y = 12>
<cfoutput>#SumN(x,y)#<cfoutput>

The following, similar code is more likely to result in programming errors:

<cfscript>
   function SumN(x,y)
   { return x + y; }
</cfscript>
<cfset x = 10>
<cfset y = 12>
<cfoutput>#SumN(x,y)#<cfoutput>


Defining functions in CFScript

You define functions using CFScript in a manner similar to defining JavaScript functions. You can define multiple functions in a single CFScript block.

Note: For more information on using CFScript, see Extending ColdFusion Pages with CFML Scripting.


CFScript function definition syntax

A CFScript function definition has the following syntax.

function functionName( [argName1[, argName2...]] )
{
   CFScript Statements
}
functionName

The name of the function. You cannot use the name of a standard ColdFusion function or any name that starts with “cf”. You cannot use the same name for two different function definitions. Function names cannot include periods.

argName1...

Names of the arguments required by the function. The number of arguments passed into the function must equal or exceed the number of arguments in the parentheses at the start of the function definition. If the calling page omits any of the required arguments, ColdFusion generates a mismatched argument count error.

The body of the function definition must consist of one or more valid CFScript statements. The body must be in curly braces, even if it is a single statement.

The following two statements are allowed only in function definitions:

var variableName = expression;

Creates and initializes a variable that is local to the function (function variable). This variable has meaning only inside the function and is not saved between calls to the function. It has precedence in the function body over any variables with the same name that exist in any other scopes. You never prefix a function variable with a scope identifier, and the name cannot include periods. The initial value of the variable is the result of evaluating the expression. The expression can be any valid ColdFusion expression, including a constant or even another UDF.

All var statements must be at the top of the function declaration, before any other statements. You must initialize all variables when you declare them. You cannot use the same name for a function variable and an argument.

Each var statement can initialize only one variable.

You should use the var statement to initialize all function-only variables, including loop counters and temporary variables.

return expression;

Evaluates expression (which can be a variable), returns its value to the page that called the function, and exits the function. You can return any ColdFusion variable type.


A simple CFScript example

The following example function adds the two arguments and returns the result:

<cfscript>
function Sum(a,b)
{
      var sum = a + b;
      return sum;
}
</cfscript>

In this example, a single line declares the function variable and uses an expression to set it to the value to be returned. This function can be simplified so that it does not use a function variable, as follows:

function MySum(a,b) {Return a + b;}

You must always use curly braces around the function definition body, even if it is a single statement.


Using the Arguments scope in CFScript

A function can have optional arguments that you do not have to specify when you call the function. To determine the number of arguments passed to the function, use the following function:

ArrayLen(Arguments)

When you define a function using CFScript, the function must use the Arguments scope to retrieve the optional arguments. For example, the following SumN function adds two or more numbers together. It requires two arguments and supports any number of additional optional arguments. You can refer to the first two, required, arguments as Arg1 and Arg2 or as Arguments[1] and Arguments[2]. You must refer to the third, fourth, and any additional optional arguments as Arguments[3], Arguments[4], and so on.

function SumN(Arg1,Arg2)
{
   var arg_count = ArrayLen(Arguments);
   var sum = 0;
   var i = 0;
   for( i = 1 ; i LTE arg_count; i = i + 1 )
   {
      sum = sum + Arguments[i];
   }
   return sum;
}

With this function, any of the following function calls are valid:

SumN(Value1, Value2)
SumN(Value1, Value2, Value3)
SumN(Value1, Value2, Value3, Value4)

and so on.

Note that the code never uses the Arg1 and Arg2 argument variables directly, because their values are always the first two elements in the Arguments array and it is simpler to step through the array. Specifying Arg1 and Arg2 in the function definition ensures that ColdFusion generates an error if you pass the function one or no arguments.

Note: Avoid referring to a required argument in the body of a function by both the argument name and its place in the Arguments scope array or structure, as this can be confusing and makes it easier to introduce errors.

For more information on the Arguments scope, see About the Arguments scope.


Defining functions using the cffunction tag

The cffunction and cfargument tags let you define functions in CFML without using CFScript.

Note: This chapter describes how to use the cffunction tag to define a function that is not part of a ColdFusion component. For information on ColdFusion components, see Building and Using ColdFusion Components. For more information on the cffunction tag, see the CFML Reference.


The cffunction tag function definition format

A cffunction tag function definition has the following format:

<cffunction name="functionName" [returnType="type" roles="roleList"
      access="accessType" output="Boolean"]>
   <cfargument name="argumentName" [Type="type" required="Boolean"
      default="defaultValue">]
   .
   .
   Function body code
   .
   .
   <cfreturn expression>
</cffunction>

where square brackets ([]) indicate optional arguments. You can have any number of cfargument tags.

The cffunction tag specifies the name you use when you call the function. You can optionally specify other function characteristics, as described in the following table.

Attribute
Description
name
The function name.
returnType
(Optional) The type of data that the function returns. The valid standard type names are: any, array, binary, boolean, date, guid, numeric, query, string, struct, uuid, variableName and void. If you specify any other name ColdFusion requires the argument to be a ColdFusion component with that name.
ColdFusion throws an error if you specify this attribute and the function tries to return data with a type that ColdFusion cannot automatically convert to the one you specified. For example, if the function returns the result of a numeric calculation, a returnType attribute of string or numeric is valid, but array is not.
roles
(Optional) A comma-delimited list of security roles that can invoke this method. If you omit this attribute, ColdFusion does not restrict user access to the function.
If you use this attribute, the function executes only if the current user is logged in using the cfloginuser tag and is a member of one or more of the roles specified in the attribute. Otherwise, ColdFusion throws an unauthorized access exception. For more information on user security, see Securing Applications.
output
(Optional) Determines how ColdFusion processes displayable output in the function body.
If you do not specify this option, ColdFusion treats the body of the function as normal CFML. As a result, text and the result of any cfoutput tags in the function definition body are displayed each time the function executes.
If you specify True or "yes", the body of the function is processed as if it were in a cfoutput tag. ColdFusion displays variable values and expression results if you surround the variables and expressions with pound signs.
If you specify False or "no" the function is processed as if it were in a cfsilent tag. The function does not display any output. The code that calls the function is responsible for displaying any function results.

You must use cfargument tags for required function arguments and named optional arguments. All cfargument tags must precede any other CFML code in cffunction tag body. Therefore, put the cfargument tags immediately following the cffunction opening tag. The cfargument tag takes the following attributes:

Attribute
Description
name
The argument name.
type
(Optional) the data type of the argument. The type of data that is passed to the function. The valid standard type names are: any, array, binary, boolean, date, guid, numeric, query, string, struct, uuid, and variableName. If you specify any other name ColdFusion requires the argument to be a ColdFusion component with that name.
ColdFusion throws an error if you specify this attribute and the function is called with data of a type that ColdFusion cannot automatically convert to the one you specified. For example, if the argument type attribute is numeric, you cannot call the function with an array.
required
(Optional) a Boolean value specifying whether the argument is required, If set to True and the argument is omitted from the function call, ColdFusion throws an error. The default if False.
Because you do not identify arguments when you call a function, all cfargument tags that specify required arguments must precede any cfargument tags that specify optional arguments in the cffunction definition.
default
(Optional) the default value for an optional argument if no argument bale is passed.
If you specify this attribute, an error occurs if you specify this attribute and set the required attribute to True.

Note: The cfargument tag is not required for optional arguments. This feature is useful if a functions can take an indeterminate number of arguments. If you do not use the cfargument tag for an optional argument, reference it using its position in the Arguments scope array. For more information see Using the Arguments scope as an array


Function-only variables and the This scope

You can create variables that exist only inside the function by assigning them to the This scope. These variables are only accessible inside the current instance of the function. As soon as the function exits, all the variables in this scope are removed.

Variables in the This scope are equivalent to the function local variables that you define using the var statement when you create a function in CFScript. However, unlike with CFScript, you must use the scope identifier, This, when you create or use the variable.

The following example shows the use of the This scope for a temporary variable, sum. (This function is equivalent to the one defined using CFScript in Defining functions in CFScript A simple CFScript example.)

<cffunction name="sum" >
   <cfargument name="var1">
   <cfargument name="var2">
   <cfset this.sum = var1 + var2 >
   <cfreturn this.sum>
</cffunction>


Using a CFML tag in a user-defined function

The most important advantage of using the cffunction tag over defining a function in CFScript is that you can include CFML tags in the function. Thus, UDFs can encapsulate activities, such as database lookups, that require ColdFusion tags. Also, you can use the cfoutput tag to display output on the calling page with minimal coding.

The following example function looks up and returns an employee’s department ID. It takes one argument, the employee ID, and looks up the corresponding department ID in the CompanyInfo Employee table:

<cffunction name="getDeptID" >
   <cfargument name="empID" required="true" type="numeric">
   <cfquery dataSource="CompanyInfo" name="deptID">
      SELECT Dept_ID
      FROM Employee
      WHERE Emp_ID = #empID#
   </cfquery>
   <cfreturn deptID.Dept_ID>
</cffunction>

Note: The cfquery tag automatically puts the query result in the Variables scope, so you cannot limit its result to the This scope.


Using the Arguments scope in cffunction definitions

When you define a function using the cffunction tag, you generally refer to the arguments directly by name if all arguments are named in the cfargument tags. If you do use the Arguments scope identifier, follow the rules listed in About the Arguments scope.


Calling functions and using variables

You can call a function anywhere that you can use an expression, including in pound signs (#) in a cfoutput tag, in a CFScript, or in a tag attribute value. One function can call another function, and you can use a function as an argument to another function.

You call user-defined functions the same way you call any built-in ColdFusion functions.


Passing arguments

ColdFusion passes the following data types to the function by value:

  • Integers
  • Real numbers
  • Strings (including lists)
  • Date-time objects
  • Arrays

As a result, any changes that you make in the function to these arguments do not affect the variable that was used to call the function, even if the calling code is on the same CFML page as the function definition.

ColdFusion passes queries, structures, and external objects such as COM objects into the function by reference. As a result, any changes to these arguments in the function also change the value of the variable in the calling code.

For an example of the effects of passing arguments, see Passing complex data.


Referencing caller variables

A function can use and change any variable that is available in the calling page, including variables in the caller’s Variables (local) scope, as if the function was part of the calling page. For example, if you know that the calling page has a local variable called Customer_name (and there is no function scope variable named Customer_name) the function can read and change the variable by referring to it as Customer_name or (using better coding practice) Variables.Customer_name. Similarly, you can create a local variable inside a function and then refer to it anywhere in the calling page after the function call. You cannot refer to the variable before you call the function.

However, you should generally avoid using the caller’s variables directly inside a function. Using the caller’s variables creates a dependency on the caller. You must always ensure that the code outside the function uses the same variable names as the function. This can become difficult if you call the function from many pages.

You can avoid these problems by using only the function arguments and the return value to pass data between the caller and the function. Do not reference calling page variables directly in the function. As a result, you can use the function anywhere in an application (or even in multiple applications), without concern for the calling code’s variables.

As with many programming practice, there are valid exceptions to this recommendation. For example you might do any of the following:

  • Use a shared scope variable, such as an Application or Session scope counter variable.
  • Use the Request scope to store variables used in the function, as shown in Using the Request scope for static variables and constants.).
  • Create context-specific functions that work directly with caller data if you always synchronize variable names.

Note: If your function must directly change a simple variable in the caller (one that is not passed to the function by reference), you can place the variable inside a structure argument.


Using function-only and This scope variables

Make sure to use the var statement or the This scope identifier to declare all function-specific variables, such as loop indexes and temporary variables that are required only for the duration of the function call. Doing this ensures that these variables are available inside the function only, and makes sure that the variable names do not conflict with the names of variables in other scopes. If the calling page has variables of the same name, the two variables are independent and do not affect each other.

For example, if a ColdFusion page has a cfloop tag with an index variable i, and the tag body calls a CFScript UDF that also has a loop with a function-only index variable i, the UDF does not change the value of the calling page loop index, and the calling page does not change the UDF index. so you can safely call the function inside the cfloop tag body.

In general, use the var statement or This scope identifier to declare all variables, other than the function arguments or shared-scope variables, that you use only inside functions. Use another scope, however, if the value of the variable must persist between function calls; for example, for a counter that the function increments each time it is called.


Using arguments

Function arguments can have the same names, but different values, as variables in the caller. Avoid such uses for clarity, however.

The following rules apply to argument persistence:

  • Because simple variable and array arguments are passed by value, their names and values exist only while the function executes.
  • Because structures, queries, and objects such as COM objects are passed by reference, the argument name exists only while the function executes, but the underlying data persists after the function returns and can be accessed by using the caller’s variable name. The caller’s variable name and the argument name can, and should, be different.

Note: If a function must use a variable from another scope that has the same name as a function-only variable, prefix the external variable with its scope identifier, such as Variables or Form. (However, remember that using variables from other scopes directly in your code is often poor practice.)


A User-defined Function Example

The following simple function takes a principal amount, an annual percentage rate, and a loan duration in months and returns the total amount of interest to be paid over the period. You can optionally use the percent sign for the percentage rate, and include the dollar sign and comma separators for the principal amount.

You could use the TotalInterest function in a cfoutput tag of a form’s action page as follows:

<cfoutput>
   Loan amount: #Form.Principal#<br>
   Annual percentage rate: #Form.AnnualPercent#<br>
   Loan duration: #Form.Months# months<br>
   TOTAL INTEREST: #TotalInterest(Form.Principal, Form.AnnualPercent,
      Form.Months)#<br>
</cfoutput>


Defining the function using CFScript

<cfscript>
function TotalInterest(principal, annualPercent, months)
{
   Var years = 0;
   Var interestRate = 0;
   Var totalInterest = 0;
   principal = trim(principal);
   principal = REReplace(principal,"[\$,]","","ALL");
   annualPercent = Replace(annualPercent,"%","","ALL");
   interestRate = annualPercent / 100;
   years = months / 12;
   totalInterest = principal*(((1+ interestRate)^years)-1);
   Return DollarFormat(totalInterest);
}
</cfscript>


Reviewing the code

The following table describes the code:

Code
Description
function TotalInterest(principal, annualPercent,
   months)
{
Starts the TotalInterest function definition. Requires three variables: the principal amount, the annual percentage rate, and the loan duration in months.
Var years = 0;
Var interestRate = 0;
Var totalInterest = 0;
Declares intermediate variables used in the function and initializes them to 0. All var statements must precede the rest of the function code.
principal = trim(principal);
principal = REReplace(principal,"[\$,]","","ALL");
annualPercent =
   Replace(annualPercent,"%","","ALL");
interestRate = annualPercent / 100;
years = months / 12;
Removes any leading or trailing spaces from the principal argument. Removes any dollar sign ($) and comma (,) characters from the principal argument to get a numeric value.
Removes any percent (%) character from the annualPercent argument to get a numeric value, then divides the percentage value by 100 to get the interest rate.
Converts the loan from months to years.
   totalInterest = principal*(((1+
interestRate)^years)-1);
   Return DollarFormat(totalInterest);
}
Calculates the total amount of interest due. It is possible to calculate the value in the Return statement, but this example uses an intermediate totalInterest variable to make the code easier to read. Returns the result formatted as a US currency string.
Ends the function definition.


Defining the function using the cffunction Tag

<cffunction name="TotalInterest">
   <cfargument name="principal" required="Yes">
   <cfargument name="annualPercent" required="Yes">
   <cfargument name="months" required="Yes">
   <cfset This.years = 0>
   <cfset This.interestRate = 0>
   <cfset This.totalInterest = 0>
   <cfset principal = trim(principal)>
   <cfset principal = REReplace(principal,"[\$,]","","ALL")>
   <cfset annualPercent = Replace(annualPercent,"%","","ALL")>
   <cfset This.interestRate = annualPercent / 100>
   <cfset This.years = months / 12>
   <cfset This.totalInterest = principal*
         (((1+ This.interestRate)^This.years)-1)>
   <cfreturn DollarFormat(This.totalInterest)>
</cffunction>

The code replaces CFScript statements with their equivalent CFML tags. In particular, note the use of the This scope for function-local variables.


Using UDFs Effectively

This section provides information that will help you use user-defined functions more effectively.


Using Application.cfm and function include files

Consider the following techniques for making your functions available to your ColdFusion pages:

  • If you consistently call a small number of UDFs, consider putting their definitions on the Application.cfm page.
  • If call UDFs in only a few of your application pages, do not include their definitions in Application.cfm.
  • If you use many UDFs, put their definitions on one or more ColdFusion pages that contain only UDFs. You can include the UDF definition page in any page that calls the UDFs.

The next section describes other techniques for making UDFs available to your ColdFusion pages.


Specifying the scope of a function

User-defined function names are essentially ColdFusion variables. ColdFusion variables are names for data. Function names are names (references) for segments of CFML code. Therefore, like variables, functions belong to scopes


About functions and scopes

Like ColdFusion variables, UDFs exist in a scope:

  • When you define a UDF, ColdFusion puts it in the Variables scope.
  • You can assign a UDF to a scope the same way you assign a variable to a scope, by assigning the function to a name in the new scope. For example, the following line assigns the MyFunc UDF to the Request scope:

    • <cfset Request.MyFunc = Variables.MyFunc>

    You can now use the function from any page in the Request scope by calling Request.MyFunc.


Selecting a function scope

The following table discusses the advantages and disadvantages of scopes that you might considering using for your functions.

Scope
Considerations
Application
Makes the function available across all invocations of the application. Unlike with functions defined in Application.cfm or included from other ColdFusion pages, all pages use the same in-memory copy of the function. Using an Application scope function can save memory and the processing required to define a function multiple times. However, Application scope functions have the following limitations:
  • You must lock the code that puts the function name in the Application scope, but you do not have to lock code that calls the function.
  • Application scope functions can cause processing bottlenecks, because the server can only execute one copy of the function at a time. All requests that require the function must wait their turn.
Request
Makes the function available for the life of the current HTTP request, including in all custom tags and nested custom tags. This scope is useful if a function is used in a page and in the custom tags it calls, or in nested custom tags.
Server
Makes the function available to all pages on a single server. In most cases, this scope is not a good choice because in clustered systems, it only makes the function available on a single server, and all code that uses the function must be inside a cflock block.
Session
Makes the function available to all pages during the current user session. This scope has no significant advantages over the Application scope.


Using the Request scope

You can effectively manage functions that are used in application pages and custom tags by doing the following:

  1. Define the functions on a function definitions page.
  2. On the functions page, assign the functions to the request scope.
  3. Use a cfinclude tag to include the function definition page on the application page, but do not include it on any custom tag pages.
  4. Always call the functions using the request scope.

This way you only need to include the functions once per request and they are available throughout the life of the request. For example, create a myFuncs.cfm page that defines your functions and assigns them to the Request scope using syntax such as the following:

function MyFunc1(Argument1, Argument2)
{ Function definition goes here }
Request.MyFunc1 = MyFunc1

The application page includes the myFuncs.cfm page:

<cfinclude template="myfuncs.cfm">

The application page and all custom tags (and nested custom tags) call the functions as follows:

Request.MyFunc1(Value1, Value2)


Using the Request scope for static variables and constants

This section describes how to partially break the rule described in the section Referencing caller variables. Here, the function defines variables in the Request scope. However, it is a specific solution to a specific issue, where:

  • Your function initializes a large number of variables.
  • The variables have either of the following characteristics:
    • They must be static: they are used only in the function, the function can change their values, and their values must persist from one invocation of the function to the next.
    • They are named constants; that is the variable value never changes.
  • Your application page (and any custom tags) calls the function multiple times.
  • You can assure that the variable names are used only by the function.

In these circumstances, you can improve efficiency and save processing time by defining your function’s variables in the Request scope, rather than the Function scope. The function tests for the Request scope variables and initializes them if they do not exist. In subsequent calls, the variables exist and the function does not reset them.

The NumberAsString function, written by Ben Forta and available from www.cflib.org takes advantage of this technique.


Using function names as function arguments

Because function names are ColdFusion variables, you can pass a function’s name as an argument to another function. This technique allows a function to use another function as a component. For example, a calling page can call a calculation function, and pass it the name of a function that does some subroutine of the overall function.

This way, the calling page could use a single function for different specific calculations, such as calculating different forms of interest. The initial function provides the framework, while the function whose name is passed to it can implement a specific algorithm that is required by the calling page.

The following simple example illustrates this use. The binop function is a generalized function that takes the name of a function that performs a specific binary operation and two operands. The binop function simply calls the specified function and passes it the operands. This code defines a single operation function, the sum function. A more complete implementation would define multiple binary operations.

<cfscript>
function binop(operation, operand1, operand2)
{ return (operation(operand1, operand2); }
function sum(addend1, addend2)
{ return addend1 + addend2;}
x = binop(sum, 3, 5);
writeoutput(x);
</cfscript>


Handling query results using UDFs

When you call a user-defined function in the body of a tag that has a query attribute, such as a cfloop query=... tag, any function argument that is a query column name passes a single element of the column, not the entire column. Therefore, the function must manipulate a single query element.

For example, the following code defines a function to combine a single first name and last name to make a full name. It queries the CompanyInfo database to get the first and last names of all employees, then it uses a cfoutput tag to loop through the query and call the function on each row in the query.

<cfscript>
function FullName(aFirstName, aLastName)
 { return aFirstName & " " & aLastName; }
</cfscript>

<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName
   FROM Employee
</cfquery>

<cfoutput query="GetEmployees">
#FullName(FirstName, LastName)#<br>
</cfoutput>

You generally use functions that manipulate many rows of a query outside tags that loop over queries. Pass the query to the function and loop over it inside the function. For example, the following function changes text in a query column to uppercase. It takes a query name as an argument:

function UCaseColumn(myquery, colName)
{
   var currentRow = 1;
   for (; currentRow lte myquery.RecordCount;
      currentRow = currentRow + 1)
   {
      myquery[colName][currentRow] =
         UCase(myquery[colName][currentRow]);
   }
   Return "";
}

The following code uses a script that calls the UCaseColumn function to convert all the last names in the GetEmployees query to uppercase. It then uses cfoutput to loop over the query and display the contents of the column.

<cfscript>
   UCaseColumn(GetEmployees, "LastName");
</cfscript>
<cfoutput query="GetEmployees">
   #LastName#<br>
</cfoutput>


Identifying and checking for UDFs

You can use the IsCustomFunction function to determine whether a name represents a user-defined function. The IsCustomFunction function generates an error if its argument does not exist. As a result, you must ensure that the name exists before calling the function, for example, by calling the IsDefined function. The following code shows this use:

<cfscript>
if( IsDefined("MyFunc"))
   if( IsCustomFunction( MyFunc ))
      WriteOutput("MyFunc is a user-defined function");
   else
      WriteOutput("Myfunc is defined but is NOT a user-defined function");
else
   WriteOutput("MyFunc is not defined");
</cfscript>

Note that you do not surround the argument to IsCustomFunction in quotation marks. As a result, you can use this function to determine if function arguments are themselves functions.


Using the Evaluate function

If your user-defined function uses the Evaluate function on arguments that contain strings, you must make sure that all variable names you use as arguments include the scope identifier. Doing so avoids conflicts with function-only variables.

The following example returns the result of evaluating its argument. It produces the expected results, the value of the argument, if you pass the argument using its fully scoped name, Variables.myname. However, the function returns the value of the function local variable if you pass the argument as myname, without the Variables scope identifier.

<cfscript>
   myname = "globalName";
   function readname( name )
   {
      var myname = "localName";
      return (Evaluate( name ));
   }
</cfscript>

<cfoutput>
<!--- This one collides with local variable name --->
   The result of calling readname with myname is:
         #readname("myname")# <br>
<!--- This one finds the name passed in  --->
   The result of calling readname with Variables.myname is:
#readname("Variables.myname")#
</cfoutput>


Passing complex data

Structures, queries, and complex objects such as COM objects are passed to UDFs by reference, so the function uses the same copy of the data as the caller. Arrays are passed to user-defined functions by value, so the function gets a new copy of the array data and the array in the calling page is unchanged by the function. As a result, you must handle arrays differently from all other complex data types.


Passing structures, queries, and objects

If you want your function to modify the caller’s copy of a structure, query, or object pass the variable as an argument. Because the function gets a reference to the caller’s structure, the caller variable reflects all changes in the function. You do not need to return the structure to the caller. After the function, returns, the calling page accesses the changed data by using the structure variable that it passed to the function.

If you do not want a function to modify the caller’s copy of a structure, query, or object, use the Duplicate function to make a copy and pass the copy to the function.


Passing Arrays

If you want your function to modify the caller’s copy of the array, the simplest solution is to pass the array to the function and return the changed array to the caller in the function return statement. In the caller, use same variable name in the function argument and return variable.

The following example shows how to directly pass and return arrays. In this example, the doubleOneDArray function doubles the value of each element in a one-dimensional array.

<cfscript>
//Initialize some variables
//This creates a simple array.
a=ArrayNew(1);
a[1]=2;
a[2]=22;
//Define the function.
function doubleOneDArray(OneDArray)
{
   var i = 0;
   for ( i = 1; i LE arrayLen(OneDArray); i = i + 1)
      { OneDArray[i] = OneDArray[i] * 2; }
   return OneDArray;
}
//Call the function.
a = doubleOneDArray(a);
</cfscript>
<cfdump var="#a#">

This solution is simple, but it is not always optimal:

  • This technique requires ColdFusion to copy the entire array twice, once when you call the function and once when the function returns. This is inefficient for large arrays and can reduce performance, particularly if the function is called frequently.
  • You may want to use the return value of other purposes, such as a status variable.

If you do not want to use the return statement to return the array to the caller, you can pass the array as an element in a structure and change the array values inside the structure. The calling page can then access the changed data by using the structure variable it passed to the UDF

The following code shows how to rewrite the previous example using an array in a structure. It returns True as a status indicator to the calling page and uses the structure to pass the array data back to the calling page.

<cfscript>
//Initialize some variables.
//This creates an simple array as an element in a structure.
arrayStruct=StructNew();
arrayStruct.Array=ArrayNew(1);
arrayStruct.Array[1]=2;
arrayStruct.Array[2]=22;
//Define the function.
function doubleOneDArrayS(OneDArrayStruct)
{
   var i = 0;
   for ( i = 1; i LE arrayLen(OneDArrayStruct.Array); i = i + 1)
      { OneDArrayStruct.Array[i] = OneDArrayStruct.Array[i] * 2; }
   return True;
}
//Call the function.
Status = doubleOneDArrayS(arrayStruct);
WriteOutput("Status: " & Status);
</cfscript>
</br>
<cfdump var="#arrayStruct#">

Note that you must use the same structure element name for the array (in this case Array) in the calling page and the function.


Using recursion

A recursive function is a function that calls itself. Recursive functions are useful when a problem can be solved by an algorithm that repeats the same operation multiple times using the results of the preceding repetition. Factorial calculation, used in the following example, is one case where recursion is useful. The Towers of Hanoi game is also solved using a recursive algorithm.

A recursive function, like looping code, must have an end condition that always stops the function. Otherwise, the function will continue until a system error occurs or you stop the ColdFusion Server.

The following example calculates the factorial of a number, that is, the product of all the integers from 1 through the number. For example, 4 factorial is 4 X 3 X 2 X 1 = 24.

function Factorial(factor)
{
   If (factor LTE 1)
      return 1;
   else
      return factor * Factorial(factor -1);
}

If the function is called with a number greater than 1, it calls itself using an argument one less than it received. It multiplies that result by the original argument, and returns the result. Therefore, the function keeps calling itself until the factor is reduced to 1. The final recursive call returns 1, and the preceding call returns 2 * 1, and so on until all the initial call returns the end result.

Caution:If a recursive function calls itself too many times, it causes a stack overflow. Always test any recursive functions under conditions that are likely to cause the maximum number of recursions to ensure that they do not cause a stack overflow.


Handling errors in UDFs

This section discusses the following topics:

  • Displaying error messages directly in the function
  • Returning function status information to the calling page
  • Using try/catch or cftry/cfcatch blocks and the cfthrow and cfrethrow tags to handle and generate exceptions

The technique you use depends on the circumstances of your function and application and on your preferred programming style. However, most functions should use the second or third technique, or a combination of the two. The following sections discuss the uses, advantages, and disadvantages of each technique, and provides examples of their use.


Displaying error messages

Your function can test for errors and use the WriteOutput function to display an error message directly to the user. This method is particularly useful for providing immediate feedback to users for simple input errors. You can use it independently or in conjunction with either of the other two error-handling methods.

For example, the following variation on a "Hello world" function displays an error message if you do not enter a name in the form:

<cfform method="POST" action="#CGI.script_name#">
   <p>Enter your Name:&nbsp;
   <input name="name" type="text" hspace="30" maxlength="30">
   <input type="Submit" name="submit" value="OK">
</cfform>
<cfscript>
   function HelloFriend(Name)
   {
      if (Name is "") WriteOutput("You forgot your name!");
      else WriteOutput("Hello " & name &"!");
      return "";
   }
  if (IsDefined("Form.submit")) HelloFriend(Form.name);
</cfscript>


Reviewing the code

The following table describes the code:

Code
Description
<cfform method="POST" action="#CGI.script_name#">
   <p>Enter your Name:&nbsp;
   <input name="name" type="text" hspace="30"
      maxlength="30">
   <input type="Submit" name="submit" value="OK">
</cfform>
Creates a simple form requesting you to enter your name.
Uses the script_name CGI variable to post to this page without specifying a URL.
If the you do not enter a name, the form posts an empty string as the name field.
<cfscript>
   function HelloFriend(Name)
   {
      if (Name is "") WriteOutput("You forgot your
         name!");
      else WriteOutput("Hello " & name &"!");
      return "";
   }
   if (IsDefined("Form.submit"))
      HelloFriend(Form.name);
</cfscript>
Defines a function to display "Hello name!" First, checks whether the argument is an empty string. If so, displays an error message.
Otherwise displays the hello message.
Returns the empty string. (The caller does not use the return value). Note that there is no need to use curly braces around the if or else statement bodies because they are single statements.
If this page has been called by submitting the form, calls the HelloFriend function. Otherwise, the page just displays the form.


Providing status information

In some cases, such as those where the function cannot provide a corrective action, the function cannot, or should not, handle the error directly. In these cases, your function can return information to the calling page. The calling page must handle the error information and act appropriately.

Consider the following mechanisms for providing status information:

  • Use the return value to indicate the function status only. The return value can be a Boolean success/failure indicator. The return value can also be a status code, for example where 1 indicates success, and various failure types are assigned known numbers. With this method, the function must set a variable in the caller to the value of a successful result.
  • Set a status variable that is available to the caller (not the return variable) to indicate success or failure and any information about the failure. With this method, the function can return the result directly to the caller. In this method, the function should use only the return value and structure arguments to pass the status back to the caller.

Each of these methods can have variants, and each has advantages and disadvantages. Which technique you use should depend on the type of function, the application in which you use it, and your coding style.

The section Passing complex data shows a simple form of the first method, a simple error status return. If the function completes successfully, it returns the word "success".

The following example, which modifies the function used in A User-defined Function Example, uses one version of the status variable method. It provides two forms of error information:

  • It returns -1, instead of an interest value, if it encounters an error. This value can serve as an error indicator because you never pay negative interest on a loan.
  • It also writes an error message to a structure that contains an error description variable. Because the message is in a structure, it is available to both the calling page and the function.


The TotalInterest function

After changes to handle errors, the TotalInterest function looks like the following. Code that is changed from the example in A User-defined Function Example is in bold.

<cfscript>
function TotalInterest(principal, annualPercent, months, status)
{
   Var years = 0;
   Var interestRate = 0;
   Var totalInterest = 0;
   principal = trim(principal);
   principal = REReplace(principal,"[\$,]","","ALL");
   annualPercent = Replace(annualPercent,"%","","ALL");
   if ((principal LE 0) OR (annualPercent LE 0) OR (months LE 0))
   {
      Status.errorMsg = "All values must be greater than 0";
      Return -1;
   }
   interestRate = annualPercent / 100;
   years = months / 12;
   totalInterest = principal*(((1+ interestRate)^years)-1);
   Return DollarFormat(totalInterest);
}
</cfscript>


Reviewing the code

The following table describes the code that has been changed or added to the previous version of this example. For a description of the initial code, see A User-defined Function Example.

Code
Description
function TotalInterest(principal, annualPercent,
months, status)
The function now takes an additional argument, a status structure. Uses a structure for the status variable so that changes that the function makes affect the status structure in the caller.
   if ((principal LE 0) OR (annualPercent LE 0) OR
(months LE 0))
   {
      Status.errorMsg = "All values must be
greater than 0";
      Return -1;
   }
Checks to make sure the principal, percent rate, and duration are all greater than zero.
If any is not, sets the errorMsg key (the only key) in the Status structure to a descriptive string. Also, returns -1 to the caller and exits the function without processing further.


Calling the function

The code that calls the function now looks like the following. Code that is changed from the example in A User-defined Function Example is in bold.

<cfset status = StructNew()>
<cfset myInterest = TotalInterest(Form.Principal, Form.AnnualPercent,
   Form.Months, status)>
<cfif myInterest EQ -1>
   <cfoutput>
      ERROR: #status.errorMsg#<br>
   </cfoutput>
<cfelse>
   <cfoutput>
      Loan amount: #Form.Principal#<br>
      Annual percentage rate:
         #Form.AnnualPercent#<br>
      Loan duration: #Form.Months# months<br>
      TOTAL INTEREST: #myInterest#<br>
   </cfoutput>
</cfif>


Reviewing the code

The following table describes the code that has been changed or added:

Code
Description
<cfset status = StructNew()>
Creates a structure to hold the function status.
<cfset myInterest = TotalInterest
   (Form.Principal, Form.AnnualPercent,
   Form.Months, status)>
Calls the function. This time, the function requires four arguments, including the status variable.
<cfif myInterest EQ -1>
   <cfoutput>
      ERROR: #status.errorMsg#<br>
   </cfoutput>
If the function returns -1, there must be an error. Displays the message that the function placed in the status.errorMsg structure key.
<cfelse>
   <cfoutput>
      Loan amount: #Form.Principal#<br>
      Annual percentage rate:
         #Form.AnnualPercent#<br>
      Loan duration: #Form.Months# months<br>
      TOTAL INTEREST: #myInterst#<br>
   </cfoutput>
</cfif>
If the function does not return -1, it returns an interest value. Displays the input values and the function return value.


Using exceptions

UDFs written in CFScript can handle exceptions using the try and catch statements. UDFs written using the cffunction tag can use the cftry, cfcatch, cfthrow, and cfrethrow tags. Using exceptions corresponds to the way many functions in other programming languages handle errors, and can be an effective way to handle errors. In particular, it separates the functional code from the error-handling code, and it can be more efficient than other methods at runtime, because it does not require testing and branching.

Exceptions in UDFs have the following two dimensions:

  • Handling exceptions generated by running the UDF code
  • Generating exceptions when the UDF identifies invalid data or other conditions that would cause errors if processing continued.


Handling exceptions in UDFs

A UDF should use try/catch blocks to handle exceptions in the same conditions that any other ColdFusion application uses try/catch blocks. These are typically circumstances where the function uses an external resource, such as a Java, COM, or CORBA object, a database, or a file. When possible, your application should prevent, rather than catch, exceptions caused by invalid application data. For example, the application should prevent users from entering a zero value for a form field that is used to divide another number, rather than handling exceptions generated by dividing by zero.

When ColdFusion catches an exception, the function can use any of the following methods to handle the exception:

  • If the error is recoverable (for example, if the problem is a database timeout where a retry might resolve the issue), try to recover from the problem.
  • Display a message, as described in Displaying error messages.
  • Return an error status, as described in Providing status information.
  • If the UDF is defined using the cffunction tag, throw a custom exception, or rethrow the exception so that it will be caught by the calling ColdFusion page. For more information on throwing and rethrowing exceptions, see Handling Run-time Exceptions with ColdFusion Tags.


Generating exceptions in UDFs

If you define your function using the cffunction tag, you can use the cfthrow and cfrethrow tags to throw errors to the page that called the function. You can use this technique whenever your UDF identifies an error, instead of displaying a message or returning an error status. For example, the following code rewrites the example from Providing status information to use the cffunction tag and CFML, and to throw and handle an exception if any of the form values are not positive numbers.

The lines that identify invalid data and throw the exception are in bold. The remaining lines are equivalent to the CFScript code in the previous example. Note, however, that the code that removes unwanted characters must precede the error checking code.

<cffunction name="TotalInterest">
   <cfargument name="principal" required="Yes">
   <cfargument name="annualPercent" required="Yes">
   <cfargument name="months" required="Yes">
   <cfset principal = trim(principal)>
   <cfset principal = REReplace(principal,"[\$,]","","ALL")>
   <cfset annualPercent = Replace(annualPercent,"%","","ALL")>

   <cfif ((principal LE 0) OR (annualPercent LE 0) OR (months LE 0))>
      <cfthrow type="InvalidData" message="All values must be greater
than 0.">
   </cfif>

   <cfset This.years = 0>
   <cfset This.interestRate = 0>
   <cfset This.totalInterest = 0>
   <cfset This.interestRate = annualPercent / 100>
   <cfset This.years = months / 12>
   <cfset This.totalInterest = principal*
         (((1+ This.interestRate)^This.years)-1)>
   <cfreturn DollarFormat(This.totalInterest)>
</cffunction>

The code that calls the function and handles the exception looks like the following. The changed lines are in bold.

<cftry>
   <cfset status = StructNew()>
   <cfset myInterest = TotalInterest(Form.Principal, Form.AnnualPercent,
      Form.Months, status)>
   <cfoutput>
      Loan amount: #Form.Principal#<br>
      Annual percentage rate: #Form.AnnualPercent#<br>
      Loan duration: #Form.Months# months<br>
      TOTAL INTEREST: #myInterest#<br>
   </cfoutput>
<cfcatch type="InvalidData">
   <cfoutput>
      #cfcatch.message#<br>
   </cfoutput>
</cfcatch>
</cftry>
Previous


Creating and Using Custom CFML Tags

This chapter describes how to create and use custom CFML tags that encapsulate common code.

Contents
  • Creating custom tags
  • Passing data to custom tags
  • Managing custom tags
  • Executing custom tags
  • Nesting custom tags
Next


Creating custom tags

Custom tags let you extend CFML by adding your own tags to the ones supplied with ColdFusion. After you define a custom tag, you can use it on a ColdFusion page just as you would any of the standard CFML tags, such as cfquery and cfoutput.

You use custom tags to encapsulate your application logic so that it can be referenced from any ColdFusion page. Custom tags allow for rapid application development and code reuse while offering off-the-shelf solutions for many programming chores.

For example, you might create a custom tag, named cf_happybirthday, to generate a birthday message. You could then use that tag in a ColdFusion page as follows:

<cf_happybirthday name="Ted Cantor" birthDate="December 5, 1987">

When ColdFusion processes the page containing this tag, it could output the message:

December 5, 1987 is Ted Cantor’s Birthday.
Please wish him well.

A custom tag can also have a body and end tag, for example:

<cf_happybirthdayMessge name="Ellen Smith" birthDate="June 8, 1993">
   <P> Happy Birthday Ellen!</P>
   <P> May you have many more!</P>
</cf_happybirthdayMessge>

This tag could output the message:

June 8, 1993 is Ellen Smith’s Birthday.
Happy Birthday Ellen!
May you have many more!

For more information about using end tags, see Handling end tags.


Creating and calling custom tags

You implement a custom tag with a single ColdFusion page. You then call the custom tag from a ColdFusion page by inserting the prefix cf_ before the page’s file name. The page referencing the custom tag is referred to as the calling page.

To create and call a custom tag:

  1. Create a ColdFusion page, the custom tag page, that shows the current date:
    2. <cfoutput>#DateFormat(Now())#</cfoutput>
  2. Save the file as date.cfm.
  3. Create a ColdFusion page, the calling page, with the following content:
    4. <html>
<head>
   <title>Date Custom Tag</title>
</head>
<body>

   <!--- Call the custom tag defined in date.cfm --->
   <cf_date>

</body>
</html>
  4. Save the file as callingdate.cfm.
  5. View callingdate.cfm in your browser.

    6. This custom tag returns the current date in the format DD-MMM-YY.

As you can see from this example, creating a custom tag in CFML is no different from writing any CFML page. You can use all CFML constructs, as well as HTML. You are free to use any naming convention that fits your development practice. Unique descriptive names make it easy for you and others to find the right tag.

Note: While tag names in ColdFusion pages are case-insensitive, custom tag filenames must be lowercase on UNIX.


Storing custom tag pages

You must store custom tag pages in any one of the following:

  • The same directory as the calling page
  • The cfusion\CustomTags directory
  • A subdirectory of the cfusion\CustomTags directory
  • A directory that you specify in the ColdFusion Administrator

To share a custom tag among applications in multiple directories, place it in the cfusion\CustomTags directory. You can create subdirectories to organize custom tags. ColdFusion searches recursively for the Custom Tags directory, stepping down through any existing subdirectories until the custom tag is found.

You might have a situation where you have multiple custom tags with the same name. To guarantee which tag ColdFusion calls, copy it to the same directory as the calling page. Or, use the cfmodule tag with the template attribute to specify the absolute path to the custom tag. For more information on cfmodule, see the next section.


Calling custom tags using the cfmodule tag

You can also use the cfmodule tag to call custom tags if you want to specify the location of the custom tag page. The cfmodule tag is useful if you are concerned about possible name conflicts when invoking a custom tag, or if the application must use a variable to dynamically call a custom tag at run time.

You must use either a template or name attribute in the tag, but you cannot use both. The following table lists the basic cfmodule attributes:

Attribute
Description
template
Required if the name attribute is not used. Same as the template attribute in cfinclude. This attribute:
  • Specifies a path relative to the directory of the calling page.
  • If the path value is prefixed with "/", ColdFusion searches directories explicitly mapped in the ColdFusion Administrator for the included file.
Example: <cfmodule template="../MyTag.cfm"> identifies a custom tag file in the parent directory.
name
Required if the template attribute is not used. Use period-separated names to uniquely identify a subdirectory under the CustomTags root directory.
Example: <cfmodule name="MyApp.GetUserOptions"> identifies the file GetUserOptions.cfm in the CustomTags\MyApp directory under the ColdFusion root directory.
attributes
The custom tag's attributes.

For example, the following code specifies to execute the custom tag defined by the mytag.cfm page in the parent directory of the calling page:

<cfmodule template="../mytag.cfm">

For more information on using the cfmodule tag, see the CFML Reference.


Calling custom tags using the cfimport tag

You can use the cfimport tag to import custom tags from a directory as a tag library. The following example imports the tags from the directory myCustomTags:

<cfimport prefix="mytags" taglib="myCustomTags">

Once imported, you call the custom tags using the prefix that you set when importing, as the following example shows:

<mytags:customTagName>

where customTagName corresponds to a ColdFusion application page named customTagName.cfm. If the tag takes attributes, you include them in the call:

<mytags:custom_tag_name attribute1=val_1 attribute2=val_2>

You can also include end tags when calling your custom tags, as the following example shows:

<mytags:custom_tag_name attribute1=val_1 attribute2=val_2>

...

</mytags:custom_tag_name>

ColdFusion calls the custom tag page twice for a tag that includes an end tag: once for the start tag and once for the end tag. For more information on how ColdFusion handles end tags, and how to write your custom tags to handle them, see Handling end tags.

One of the advantages to using the cfimport tag is that you can define a directory structure for your custom tags to organize them by category. For example, you can put all security tags in one directory, and all interface tags in another. You then import the tags from each directory and give them a different prefix:

<cfimport prefix="security" taglib="securityTags">
<cfimport prefix="ui" taglib="uiTags">
...
<security:validateUser name="Bob">
...
<ui:greeting name="Bob">
...

Reading your code becomes easier because you can easily identify the location of your custom tags from the prefix.


Securing custom tags

ColdFusion's security framework enables you to selectively restrict access to individual tag files and tag directories. This can be an important safeguard in team development. For details, see Administering ColdFusion Server.


Accessing existing custom tags

Before creating a custom tag in CFML, you should review the Custom Tag section of the ColdFusion Developer Exchange at http://devex.macromedia.com/developer/gallery/index.cfm. You may be able to find a tag here that does what you want.

Tags are grouped in several broad categories and are downloadable as freeware, shareware, or commercial software. You can view each tag's syntax and usage information. The gallery contains a wealth of background information on custom tags and an online discussion forum for tag topics.

Tag names with the cf_ preface are CFML custom tags; those with the cfx_ preface are ColdFusion extensions written in C++. For more information about the CFX tags, see Building Custom CFXAPI Tags.

If you do not find a tag that meets your specific needs, you can create your own custom tags in CFML.


Passing data to custom tags

To make your custom tags flexible, you will often want to pass data to them for processing. This section describes how to write custom tags that take tag attributes and other data as input from a calling page.


Passing values to and from custom tags

Because custom tags are individual ColdFusion pages, variables and other data are not automatically shared between a custom tag and the calling page. To pass data from the calling page to the custom tag, you can specify attribute name/value pairs in the custom tag, just as you do for normal HTML and CFML tags.

For example, to pass the value of the NameYouEntered variable to the cf_getmd tag, you can call the custom tag as follows:

<cf_getmd Name=#NameYouEntered#>

To pass multiple attributes to a custom tag, separate them with a space in the tag as follows:

<cf_mytag Firstname="Thadeus" Lastname="Jones">

In the custom tag, you use the Attributes scope to access attributes passed to the tag. Therefore, in the getmd.cfm page, you refer to the passed attribute as Attributes.Name. The mytag.cfm custom tag page refers to the passed attributes as Attributes.Firstname and Attributes.Lastname.

The custom tag page can also access variables set in the calling page by prefixing the calling page’s local variable with Caller. However, this is not the best way to pass information to a custom tag, because each calling page would be required to create variables with the names required by the custom tag. You can create more flexible custom tags by passing parameters using attributes.

Variables created within a custom tag are deleted when the processing of the tag terminates. Therefore, if you want to pass information back to the calling page, you must write that information back to the Caller scope of the calling page. You cannot access the custom tag’s variables outside the custom tag itself.

For example, use the following code in the getmd.cfm page to set the variable Doctor on the calling page:

<cfset Caller.Doctor="Doctor " & Attributes.Name>

If the variable Doctor does not exist in the calling page, this statement creates it. If the variable exists, the custom tag overwrites it.

The following figure shows the relationship between the variables on the calling page and the custom tag:

This is a picture of the feature being described.

One common technique used by custom tags is for the custom tag to take as input an attribute containing the name of the variable to use to pass back results. For example, the calling page passes returnHere as the name of the variable to use to pass back results:

<cf_mytag resultName="returnHere">

In mytag.cfm, the custom tag passes back its results using the following code:

<cfset "Caller.#Attributes.resultName#" = result>

Tip: Be careful not to overwrite variables in the calling page from the custom tag. You should adopt a naming convention to minimize the chance of overwriting variables. For example, prefix the returned variable with customtagname_, where customtagname is the name of the custom tag.

Note: Data pertaining to the HTTP request or to the current application is visible in the custom tag page. This includes the variables in the Form, Url, Cgi, Request, Cookies, Server, Application, Session, and Client scopes.


Using tag attributes summary

Custom tag attribute values are passed from the calling page to the custom tag page as name-value pairs. CFML custom tags support required and optional attributes. Custom tag attributes conform to the following CFML coding standards:

  • ColdFusion passes any attributes in the Attributes scope.
  • Use the Attributes.attribute_name syntax when referring to passed attributes to distinguish them from custom tag page local variables.
  • Attributes are case-insensitive.
  • Attributes can be listed in any order within a tag.
  • Attribute name/value pairs for a tag must be separated by a space in the tag invocation.
  • Passed values that contain spaces must be enclosed in double-quotes.
  • Use the cfparam tag with a default attribute at the top of a custom tag to test for and assign defaults for optional attributes that are passed from a calling page. For example:
    • <!--- The value of the variable Attributes.Name comes from the calling page. If
the calling page does not set it, make it “Who". --->
<cfparam name="Attributes.Name" default="Who">
  • Use the cfparam tag or a cfif tag with an IsDefined function at the top of a custom tag to test for required attributes that must be passed from a calling page. For example, the following code issues an abort if the user does not specify the Name attribute to the custom tag:
    • <cfif not IsDefined("Attributes.Name")>
   <cfabort showError="The Name attribute is required.">
</cfif>


Custom tag example with attributes

The example in this section creates a custom tag that uses an attribute that is passed to it to set the value of a variable called Doctor on the calling page.

To create a custom tag:

  1. Create a new ColdFusion page (the calling page) with the following content:
    2. <html>
<head>
   <title>Enter Name</title>
</head>
<body>
<!--- Enter a name, which could also be done in a form --->
<!--- This example simply uses a cfset --->
<cfset NameYouEntered="Smith">

<!--- Display the current name --->
<cfoutput>
Before you leave this page, you're #Variables.NameYouEntered#.<br>
</cfoutput>

<!--- go to the custom tag --->
<cf_getmd Name="#NameYouEntered#">
<!--- Come back from the Custom tag --->

<!--- display the results of the custom tag --->
<cfoutput>
You are now #Variables.Doctor#.<br>
</cfoutput>
</body>
</html>
  2. Save the page as callingpage.cfm.
  3. Create another new page (the custom tag) with the following content:
    4. <!--- The value of the variable Attributes.Name comes from the calling page. If
the calling page does not set it, make it “Who". --->
<cfparam name="Attributes.Name" default="Who">

<!--- Create a variable called Doctor, make its value "Doctor "
       followed by the value of the variable Attributes.Name.
       Make its scope Caller so it is passed back to the calling page
--->
<cfset Caller.Doctor="Doctor " & Attributes.Name>
  4. Save the page as getmd.cfm.
  5. Open the file callingpage.cfm in your browser.

The calling page uses the getmd custom tag and displays the results.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfset NameYouEntered="Smith">
In the calling page, create a variable NameYouEntered and assign it the value "Smith."
<cfoutput>
Before you leave this page, you're
   #Variables.NameYouEntered#.<br>
</cfoutput>
In the calling page, display the value of the NameYouEntered variable before calling the custom tag.
<cf_getmd Name="#NameYouEntered#">
In the calling page, call the getmd custom tag and pass it the Name attribute whose value is the value of the local variable NameYouEntered.
<cfparam name="Attributes.Name"
default="Who">
The custom tag page normally gets the Name variable in the Attributes scope from the calling page. Assign it the value "Who" if the calling page did not pass an attribute.
<cfset Caller.Doctor="Doctor " &
Attributes.Name>
In the custom tag page, create a variable called Doctor in the Caller scope so it will exist in the calling page as a local variable.
Set its value to the concatenation of the string “Doctor “ and the value of the Atributes.Name variable.
<cfoutput>
You are now #Variables.Doctor#.<br>
</cfoutput>
In the calling page, display the value of the Doctor variable returned by the custom tag page. (We use the Variables scope prefix to emphasize the fact that the variable is returned as a local variable.)


Passing custom tag attributes using CFML structures

You can use the reserved attribute attributecollection to pass attributes to custom tags using a structure. The attributecollection attribute must reference a structure containing the attribute names as the keys and the attribute values as the values. You can freely mix attributecollection with other attributes when you call a custom tag.

The key-value pairs in the structure specified by attributecollection get copied into the custom tag page’s Attributes scope. This has the same effect as specifying the attributecollection entries as individual attributes when you call the custom tag. The custom tag page refers to the attributes passed using attributecollection the same way as it does other attributes; for example, as Attributes.CustomerName or Attributes.Department_number.

Note: You can use both tag attributes and attributecollections. If you pass an attribute with the same name using both methods, ColdFusion passes only the tag attribute to the custom tag and ignores the corresponding attribute from the attribute collection.

Custom tag processing reserves attributecollection to refer to the structure holding a collection of custom tag attributes. If attributecollection does not refer to such a collection, ColdFusion generates a template exception.

The following example uses an attributecollection to pass two of four attributes:

<cfset zort=StructNew()>
<cfset zort.x = "-X-">
<cfset zort.y = "-Y-">
<cf_testtwo a="blab" attributecollection=#zort# foo="16">

If testtwo.cfm contains the following code:

---custom tag ---<br>
<cfoutput>#attributes.a# #attributes.x# #attributes.y#
   #attributes.foo#</cfoutput><br>
--- end custom tag ---

its output is the following statement:

---custom tag ---
blab -X- -Y- 16
--- end custom tag ---

One use for attributecollection is to pass the entire Attributes scope of one custom tag to another. This often happens when you have one custom tag that calls a second custom tag and you want to pass all attributes from the first tag to the second.

For example, you call a custom tag with the following code:

<cf_first attr1="foo" attr2="bar">

To pass all the attributes of the first custom tag to the second, you include the following statement in first.cfm:

<cf_second attributecollection="#attributes#">

Within the body of second.cfm, you reference the parameters passed to it as follows:

<cfoutput>#attributes.attr1#</cfoutput>
<cfoutput>#attributes.attr2#</cfoutput>


Managing custom tags

If you deploy custom tags in a multideveloper environment or distribute your tags publicly, you can use the following additional ColdFusion capabilities:

  • Advanced security
  • Template encoding


Securing custom tags

ColdFusion's security framework enables you to selectively restrict access to individual tags or to tag directories. This can be an important safeguard in team development. For more information, see Securing Applications.


Encoding custom tags

You can use the command-line utility cfencode to encode any ColdFusion application page. By default, the utility is installed in the cf_root/bin directory. It is especially useful for securing custom tag code before distributing it.

The cfencode tag uses the following syntax:

cfencode infile outfile [/r /q] [/h "message"] /v"2"

The following table describes the options:

Option | Description
infile | The file you want to encode. cfencode does not process an encoded file.
outfile | Path and filename of the output file. Warning: If you do not specify an output filename, a warning message asks if you want to continue, and the encoded file will overwrite the source file.
/r | Recursive, when used with wildcards, recurses through subdirectories to encode files.
/q | Suppresses warning messages.
/h | Header, allows custom header to be written to the top of the encoded file(s).
/v | Required parameter that allows encoding using a specified version number. Use "1" for pages you want to be able to run on ColdFusion 3.x. Use "2" for pages you want to run strictly on ColdFusion 4.0 and later.

Note:

While it is possible to encode binary files with cfencode, it is not recommended.


Executing custom tags

The following sections provide information about executing custom tags, including information about handling end tags and processing body text.


Accessing tag instance data

When a custom tag page executes, ColdFusion keeps data related to the tag instance in the thisTag structure. You can access the thisTag structure from within your custom tag to control processing of the tag. The behavior is similar to the File tag-specific variable (sometimes called the File scope).

ColdFusion generates the variables in the following table and writes them to the thisTag structure:

Variable | Description
ExecutionMode | Contains the execution mode of the custom tag. Valid values are "start", "end", and "inactive".
HasEndTag | Distinguishes between custom tags that are called with and without end tags. Used for code validation. If the user specifies an end tag, HasEndTag is set to True; otherwise, it is set to False.
GeneratedContent | The content that has been generated by the tag. This includes anything in the body of the tag, including the results of any active content, such as ColdFusion variables and functions. You can process this content as a variable.
AssocAttribs | Contains the attributes of all nested tags if you use cfassociate to make them available to the parent tags. For more information, see High-level data exchange.

The following example accesses the ExecutionMode variable of the thisTag structure from within a custom tag:

<cfif thisTag.ExecutionMode is 'start'>


Handling end tags

The examples of custom tags shown so far in this chapter all reference a custom tag using just a start tag, as in:

<cf_date>

In this case, ColdFusion calls the custom tag page date.cfm to process the tag.

However, you might want to create custom tags that have both a start and an end tag. For example, the following tag has both a start and an end tag:

<cf_date>
   ...
</cf_date>

ColdFusion calls the custom tag page date.cfm twice for a tag that includes an end tag: once for the start tag and once for the end tag. As part of the date.cfm page, you can determine if the call is for the start or end tag, and perform the appropriate processing.

ColdFusion will also call the custom tag page twice if you use the shorthand form of an end tag:

<cf_date/>

You can also call a custom tag using the cfmodule tag, as shown in the following example:

<cfmodule ...>
   ...
</cfmodule>

If you specify an end tag to cfmodule, then ColdFusion calls your custom tag as if it had both a start and an end tag.


Determining if an end tag is specified

You can write a custom tag that requires users to include an end tag. If a tag must have an end tag provided, you can use thisTag.HasEndTag in the custom tag page to verify that the user included the end tag.

For example, in date.cfm, you could include the following code to determine whether the end tag is specified:

<cfif thisTag.HasEndTag is 'False'>
   <!--- Abort the tag--->
   <cfabort showError="An end tag is required.">
</cfif>


Determining the tag execution mode

The variable thisTag.ExecutionMode contains the mode of invocation of a custom tag page. The variable has one of the following values:

  • Start Mode for processing the start tag.
  • End Mode for processing the end tag.
  • Inactive Mode when the custom tag uses nested tags. For more information, see Nesting custom tags.

If an end tag is not explicitly provided, ColdFusion invokes the custom tag page only once, in Start mode.

A custom tag page named bold.cfm that bolds text could be written as follows:

<cfif thisTag.ExecutionMode is 'start'>
   <!--- Start tag processing --->
   <B>
<cfelse>
   <!--- End tag processing --->
   </B>
</cfif>

You then use this tag to convert text to bold:

<cf_bold>This is bolded text</cf_bold>

You can also use cfswitch to determine the execution mode of a custom tag:

<cfswitch expression=#thisTag.ExecutionMode#>
   <cfcase value= 'start'>
      <!--- Start tag processing --->
   </cfcase>
   <cfcase value='end'>
      <!--- End tag processing --->
   </cfcase>
</cfswitch>


Considerations when using end tags

How you code your custom tag to divide processing between the start tag and end tag is greatly dependent on the function of the tag. However, you can use the following rules to help you make your decisions:

  • Use the start tag to validate input attributes, set default values, and validate the presence of the end tag if it is required by the custom tag.
  • Use the end tag to perform the actual processing of the tag, including any body text passed to the tag between the start and end tags. For more information on body text, see Processing body text.
  • Perform output in either the start or end tag; do not divide it between the two tags.


Processing body text

Body text is any text that you include between the start and end tags when you call a custom tag. For example:

<cf_happybirthdayMessge name="Ellen Smith" birthDate="June, 8, 1993">
   <P> Happy Birthday Ellen!</P>
   <P> May you have many more!</P>
</cf_happybirthdayMessge>

In this example, the two lines of code after the start tag are the body text.

You can access the body text within the custom tag using the thisTag.GeneratedContent variable. The variable contains all body text passed to the tag. You can modify this text during processing of the tag. The contents of the thisTag.GeneratedContent variable are returned to the browser as part of the tag’s output.

The thisTag.GeneratedContent variable is always empty during the processing of a start tag. Any output generated during start tag processing is not considered part of the tag's generated content.

A custom tag can access and modify the generated content of any of its instances using the thisTag.GeneratedContent variable. In this context, the term generated content means the results of processing the body of a custom tag. This includes all text and HTML code in the body, the results of evaluating ColdFusion variables, expressions, and functions, and the results generated by descendant tags. Any changes to the value of this variable result in changes to the generated content.

As an example, consider a tag that comments out the HTML generated by its descendants. Its implementation could look something like this:

<cfif thisTag.ExecutionMode is 'end'>
   <cfset thisTag.GeneratedContent ='<!--#thisTag.GeneratedContent#-->'>
</cfif>


Terminating tag execution

Within a custom tag, you typically perform error checking and parameter validation. As part of those checks, you can choose to abort the tag, using cfabort, if a required attribute is not specified or other severe error is detected.

The cfexit tag also terminates execution of a custom tag. However, the cfexit tag is designed to give you more flexibility when coding custom tags than cfabort. The cfexit tag’s method attribute specifies where execution continues. The cfexit tag can specify that processing continues from the first child of the tag or continues immediately after the end tag marker.

You can also use the method attribute to specify that the tag body executes again. This enables custom tags to act as high-level iterators, emulating cfloop behavior.

The following table summarizes cfexit behavior:

method attribute value | Location of cfexit call | Behavior
ExitTag (default) | Base page | Acts like cfabort
 | ExecutionMode=start | Continue after end tag
 | ExecutionMode=end | Continue after end tag
ExitTemplate | Base page | Acts like cfabort
 | ExecutionMode=start | Continue from first child in body
 | ExecutionMode=end | Continue after end tag
Loop | Base page | Error
 | ExecutionMode=start | Error
 | ExecutionMode=end | Continue from first child in body


Nesting custom tags

A custom tag can call other custom tags from within it’s body text, thereby nesting tags. ColdFusion uses nested tags such as cfgraph and cfgraphdata, cfhttp and cfhttppam, and cftree and cftreeitem. The ability to nest tags allows you to provide similar functionality.

The following example shows a cftreeitem tag nested within a cftree tag:

<cftree name="tree1"
   required="Yes"
   hscroll="No">
   <cftreeitem value=fullname
      query="engquery"
      queryasroot="Yes"
      img="folder,document">
</cftree>

The calling tag is known as an ancestor, parent, or base tag, while the tags that ancestor tags call are known as descendant, child, or sub tags. Together, the ancestor and all descendant tags are called collaborating tags.

In order to nest tags, the parent tag must have a closing tag.

The following table lists the terms that describe the relationships between nested tags:

Calling tag | Tag nested within the calling tag | Description
Ancestor | Descendant | An ancestor is any tag that contains other tags between its start and end tags. A descendant is any tag called by a tag.
Parent | Child | Parent and child are synonyms for ancestor and descendant.
Base tag | Sub tag | A base tag is an ancestor that you explicitly associate with a descendant, called a sub tag, with cfassociate.

You can create multiple levels of nested tags. In this case, the sub tag becomes the base tag for its own sub tags. Any tag with an end tag present can be an ancestor to another tag.

Nested custom tags operate through three modes of processing, which are exposed to the base tags through the variable thisTag.ExecutionMode:

  • The start mode, in which the base tag is processed for the first time.
  • The inactive mode, in which sub tags and other code contained within the base tag are processed. No processing occurs in the base tag during this phase.
  • The end mode, in which the base tag is processed a second time. The end mode occurs when ColdFusion reaches the custom tag’s end tag.


Passing data between nested custom tags

A key custom tag feature is for collaborating custom tags to exchange complex data without user intervention, while encapsulating each tag's implementation so that others cannot see it.

When you decide to you use nested tags, you must address the following issues:

  • What data should be accessible?
  • Which tags can communicate to which tags?
  • How are the source and targets of the data exchange identified?
  • What CFML mechanism is used for the data exchange?


What data is accessible?

To enable developers to obtain maximum productivity in an environment with few restrictions, CFML custom tags can expose all their data to collaborating tags.

When you develop custom tags, you should document all variables that collaborating tags can access and/or modify. When your custom tags collaborate with other custom tags, you should make sure that they do not modify any undocumented data.

To preserve encapsulation, put all tag data access and modification operations into custom tags. For example, rather than documenting that the variable MyQueryResults in a tag's implementation holds a query result and expecting users to manipulate MyQueryResults directly, create a nested custom tag that manipulates MyQueryResult. This protects the users of the custom tag from changes in the tag's implementation.


Variable scopes and special variables

Use the Request scope for variables in nested tags. The Request scope is available to the base page, all pages it includes, all custom tag pages it calls, and all custom tag pages called by the included pages and custom tag pages. Collaborating custom tags that are not nested in a single tag can exchange data using the request structure. The Request scope is represented as a structure named Request.


Where is data accessible?

Two custom tags can be related in a variety of ways in a page. Ancestor and descendant relationships are important because they relate to the order of tag nesting.

A tag's descendants are inactive while the page is executed; that is, the descendent tags have no instance data. A tag, therefore, can only access data from its ancestors, not its descendants. Ancestor data is available from the current page and from the whole runtime tag context stack. The tag context stack is the path from the current tag element up the hierarchy of nested tags, including those in included pages and custom tag references, to the start of the base page for the request. Both cfinclude tags and custom tags appear on the tag context stack.


High-level data exchange

While the ability to create nested custom tags is a tremendous productivity gain, keeping track of complex nested tag hierarchies can become a chore. The cfassociate tag lets the parent know what the children are up to. By adding this tag to a sub tag, you enable communication of its attributes to the base tag.

In addition, there are many cases in which descendant tags are used only as a means for data validation and exchange with an ancestor tag, such as cfhttp/cfhttpparam and cftree/cftreeitem. You can use the cfassociate tag to encapsulate this processing.

The cfassociate tag has the following format:

<cfassociate baseTag="tagName" dataCollection="collectionName">

The baseTag attribute specifies the name of the base tag that gets access to this tag’s attributes. The dataCollection attribute specifies the name of the structure in which the base tag stores the sub-tag data. Its default value is AssocAttribs. You only need to specify a dataCollection attribute if the base tag can have more than one type of sub tag. It is convenient for keeping separate collections of attributes, one per tag type.

Note: If the custom tag requires an end tag, the code processing the structure referenced by the dataCollection attribute must be part of end-tag code.

When cfassociate is encountered in a sub tag, the sub tag’s attributes are automatically saved in the base tag. The attributes are in a structure appended to the end of an array whose name is 'thisTag.collectionName'.

The cfassociate tag performs the following operations:

<!--- Get base tag instance data --->
<cfset data = getBaseTagData(baseTag)>
<!--- Create a string with the attribute collection name --->
<cfset collection_Name = "data.#dataCollection#">
<!--- Create the attribute collection, if necessary --->
<cfif not isDefined(collectionName)>
   <cfset #collection_Name# = arrayNew(1)>
</cfif>
<!--- Append the current attributes to the array --->
<cfset temp=arrayAppend(evaluate(collectionName), attributes)>

The code accessing sub-tag attributes in the base tag could look like the following:

<!--- Protect against no sub-tags --->
<cfparam Name='thisTag.assocAttribs' default=#arrayNew(1)#>

<!--- Loop over the attribute sets of all sub tags --->
<cfloop index=i from=1 to=#arrayLen(thisTag.assocAttribs)#>

   <!--- Get the attributes structure --->
   <cfset subAttribs = thisTag.assocAttribs[i]>
   <!--- Perform other operations --->

</cfloop>


Ancestor data access

The ancestor’s data is represented by a structure object that contains all the ancestor’s data.

The following functions provide access to ancestral data:

  • GetBaseTagList() Returns a comma-delimited list of uppercase ancestor tag names, as a string. The first list element is the current tag, the next element is the parent tag name if the current tag is a nested tag. If the function is called for a top-level tag, it returns an empty string.
  • GetBaseTagData(TagName, InstanceNumber=1) Returns an object that contains all the variables (not just the local variables) of the nth ancestor with a given name. By default, the closest ancestor is returned. If there is no ancestor by the given name, or if the ancestor does not expose any data (such as cfif), an exception is thrown.


Example: Ancestor data access

This example creates two custom tags and a simple page that calls each of the custom tags. The first custom tag calls the second. The second tag reports on its status and provides information about its ancestors.

To create the calling page:

  1. Create a new ColdFusion page (the calling page) with the following content:
    2. Call cf_nesttag1 which calls cf_nesttag2<br>
<cf_nesttag1>
<hr>

Call cf_nesttag2 directly<br>
<cf_nesttag2>
<hr>
  2. Save the page as nesttest.cfm.

To create the first custom tag page:

  1. Create a new ColdFusion page with the following content:
    2. <cf_nesttag2>
  2. Save the page as nesttag1.cfm.

To create the second custom tag page:

  1. Create a new ColdFusion page with the following content:
    2. <cfif thisTag.executionmode is 'start'>
   <!--- Get the tag context stack. The list will look something like
   "MYTAGNAME, CALLINGTAGNAME, ..." --->
   <cfset ancestorlist = getbasetaglist()>

   <!--- Output your own name. You are the first entry in the context stack.
--->
   <cfoutput>
   <p>I'm custom tag #ListGetAt(ancestorlist,1)#</p>

   <!--- output all the contents of the stack a line at a time --->
   <cfloop index="loopcount" from="1" to=#listlen(ancestorlist)#>
   Ancestorlist entry #loopcount# n is #ListGetAt(ancestorlist,loopcount)#<br>
   </cfloop><br>
   </cfoutput>

   <!--- Determine whether you are nested inside a custom tag. Skip the first
element of the ancestor list, i.e., the name of the custom tag I'm in --->
   <cfset incustomtag = ''>
   <cfloop index=elem
      list=#listrest(ancestorlist)#>
      <cfif (left(elem, 3) eq 'cf_')>
         <cfset incustomtag = elem>
         <cfbreak>
      </cfif>
   </cfloop>

   <cfif incustomtag neq ''>
      <!--- Say you are there --->
      <cfoutput>
         I'm running in the context of a custom
         tag named #inCustomTag#.<p>
      </cfoutput>

      <!--- Get the tag instance data --->
      <cfset tagdata = getbasetagdata(incustomtag)>

      <!--- Find out the tag's execution mode --->
      I'm located inside the
      <cfif tagdata.thisTag.executionmode neq 'inactive'>
         custom tag code either because it is in
         its start or end execution mode.
      <cfelse>
         body of the tag
      </cfif>
      <p>
   <cfelse>
      <!--- Say you are lonely --->
      I'm not nested inside any custom tags. :^( <p>
   </cfif>
</cfif>
  2. Save the page as nesttag2.cfm.
  3. Open the file nesttest.cfm in your browser.
Previous


Building and Using ColdFusion Components

ColdFusion components let you encapsulate and re-use code in ColdFusion development, generate web services, and create Flash interfaces for your application.

Contents
  • About ColdFusion components
  • Building ColdFusion components
  • Interacting with component methods
  • Using advanced ColdFusion component functionality
Next


About ColdFusion components

ColdFusion components encapsulate application functionality and provide a standard interface for client access to that functionality. Clients access component functionality by invoking methods on components. Components support a variety of client interfaces, including web pages, Flash movies, web services, and other objects accessible from ColdFusion components and pages. Component method invocation serves as the gateway to component functionality, including passing parameters and receiving component method results.

Like other ColdFusion Markup Language (CFML) code reuse techniques, such as user-defined functions (UDFs) and custom CFML tags, components let you create application functionality that can be reused wherever you need it. If you want to modify, add, or remove component functionality, you only need to make changes in one component file.

Note: For more information about UDFs, custom tags, and other ColdFusion code reuse techniques, see Reusing Code in ColdFusion Pages.


Applying design patterns to component development

As your development projects grow larger and teams of developers become involved, ColdFusion components can structure CFML to serve as building blocks for design pattern methodologies.

Established design pattern specifications represent the accumulated knowledge of veteran software developers, which is used to establish guidelines for application development. When applied correctly, design patterns streamline software production, manage the application development process, and ensure code maintainability for the life cycle of the application.

When making the decision about whether to use a design pattern methodology for a development project, keep the following points in mind:

  • While implementing a design pattern methodology involves more planning initially, you will save time and money later in the development cycle.
  • Each design pattern methodology has strengths and weaknesses. Select the methodology that best fits your development project needs.

For more information about design patterns, see Rapid Development: Taming Wild Software Schedules, Steve McConnell, 1996: Microsoft Press.


Building ColdFusion components

Just like ColdFusion pages, you store component files in a domain accessible by your Web server and ColdFusion. Unlike ColdFusion pages, you save component files with the CFC suffix, such as componentName.cfc.

Save your component files in one of the following locations:

  • Directories accessible from the web server, which includes the web root and web server virtual directories.
  • Directories accessible from ColdFusion mappings.
  • Subdirectories of custom tag roots.

Note: For more information about saving components and component naming conventions, see Using component packages.

All ColdFusion variable scopes are available to components, including Session, Client, Server, and Application. In addition, the This scope is available during component method execution.

You use the cfcomponent and cffunction tags to create ColdFusion components. By itself, the cfcomponent tag does not provide functionality. Rather, the cfcomponent tag provides an envelope that describes the functionality that you build in CMFL and enclose in cffunction tags.

Syntax

<cfcomponent extends="anotherComponent">

The following table displays the tag attribute, data type, and description:

Attribute | Type | Required | Description | For more information
extends | string | no | Name of parent component. | See Using component inheritance.

Note: The cfcomponent tag is optional.

Syntax

<cffunction name="methodName" returnType="dataType" roles="securityRoles"
access="methodAccess" output="yes/no">

The following table displays the tag attribute, data type, and description:

Attribute | Type | Required | Description | For more information
name | string | yes | Name of component method | See Defining component methods.
returnType | string | no | Data type validation for returned values. | See Returning values from component methods.
roles | string | no | Assigns component method to ColdFusion security roles. | Building secure ColdFusion components.
access | string | no | Restricts component method access by client type. | See Building secure ColdFusion components
output | Boolean | no | Suppresses component method output | See Building secure ColdFusion components.

The following example creates a component with two methods:

<cfcomponent>
   <cffunction name="getEmp">
       <cfquery name="empQuery" datasource="ExampleApps" dbtype="ODBC" >
          SELECT FIRSTNAME, LASTNAME, EMAIL
          FROM tblEmployees
       </cfquery>
       <cfreturn empQuery>
   </cffunction>
   <cffunction name="getDept">
      <cfquery name="deptQuery" datasource="ExampleApps" dbtype="ODBC" >
          SELECT *
          FROM tblDepartments
       </cfquery>
       <cfreturn deptQuery>
   </cffunction>
</cfcomponent>

In the example, two cffunction tags define two component methods, getEmp and getDept. When invoked, the component methods query the ExampleApps database. The cfreturn tag returns the query results to the client. For more information, see Invoking component methods.


Defining component methods

Component method definitions exist between opening and closing cffunction tags. To separate the component method code from the component file, use the cfinclude tag to call the page that contains the component method code.

To create a component method:

  1. Create a new ColdFusion component, and save it as tellTime.cfc in a directory below your web root directory.
  2. Modify the code so that it appears as follows:
    3. <cfcomponent>
   <cffunction name="getLocalTime">
      <cfscript>
         serverTime=now();
         localStructure=structNew();
         localStructure.Hour=DatePart("h", serverTime);
         localStructure.Minute=DatePart("n", serverTime);
      </cfscript>
      <cfoutput>
         #localStructure.Hour#:#localStructure.Minute#
      </cfoutput>
   </cffunction>
</cfcomponent>

In the example, the cfscript and cfoutput statements execute during component method processing.
  3. Save your work.

By placing the method execution code in a separate file, template methods separate execution and markup code from the component method definitions.

To create component method using the cfinclude tag:

  1. Open the tellTime.cfc file, and modify the code so that it appears as follows:
    2. <cfcomponent>
   <cffunction name="getLocalTime">
      <cfinclude template="getTime.cfm">
   </cffunction>
</cfcomponent>

            In the example, the getLocalTime method definition calls the getTime.cfm file with the cfinclude tag.
  2. Save your work.
  3. Create a ColdFusion page, and save it as getTime.cfm in the same directory as tellTime.cfc.
  4. Modify getTime.cfm so that the code appears as follows:
    5. <cfscript>
   serverTime=now();
   localStruct=structNew();
   localStruct.Hour=DatePart("h", serverTime);
   localStruct.Minute=DatePart("n", serverTime);
</cfscript>
<cfoutput>#localStruct.Hour#:#localStruct.Minute#</cfoutput>

In the example, a CFScript statement uses the now() and DatePart() functions to populate a structure with hour and minute values. The values are then displayed with the cfoutput tag. Notice that no value is returned to the client. Instead, the getTime method displays the variable.
  5. Save your work.


Interacting with component methods

The vast majority of ColdFusion applications require data to be passed back and forth between a number of pages. For example, a typical web shopping cart application uses multiple ColdFusion pages to gather user data, access databases, and confirm credit card information.

ColdFusion components support passing and returning simple and complex values using the cfinvoke tag, URL and form controls, CFScript, the Flash Remoting service, and web services. Whether you are receiving registration information from a simple HTML page or passing a query object back to a sophisticated web service, interacting with ColdFusion components means that you must be able to pass data into and out of a component.

Interacting with components consists of the following operations:

  • Invoke a component method -- Use the cfinvoke tag in ColdFusion pages and components, the HTTP form methods GET and POST, CFScript invocation, Flash Remoting invocation, or web service invocation. For more information, see Invoking component methods.
  • Pass a parameter to a component method -- Do three things: define the parameter in the component method definition, choose a parameter-passing technique, and access the data passed in the parameter. For more information, see Passing parameters to component methods.
  • Return a value from a component method -- Do two things: insert the cfreturn tag into the component method definition to specify a variable to return to the client, and access the returned values in the client. For more information, see Returning values from component methods.


Invoking component methods

To interact with ColdFusion components, you invoke component methods from the client. Components support many client types, including web pages, ColdFusion pages, Flash movies, web services, and other components. The invocation process depends on what type of client invokes a component method.

The following table displays the different ways to invoke component methods:

Invocation | Description | For more information
cfinvoke tag | The cfinvoke tag instantiates and invokes component methods from within ColdFusion pages and components. | See Invoking component methods using the cfinvoke tag.
cfobject tag | The cfobject tag instantiates a component. However, you must still use the cfinvoke tag or CFScript to invoke component methods, pass parameters, and return results. | See Invoking component methods using the cfobject tag.
URL control (HTTP GET) | You use the component and method names in the URL string to invoke component methods. | See Invoking component methods using a URL.
Form control (HTTP POST) | HTML and ColdFusion forms invoke component methods using the HTML form and input tags and their attributes. | See Invoking component methods using a form.
CFScript | CFScript instantiates component methods using the createObject function. The component method can then be called using componentName.componetMethod() syntax. | See Invoking component methods with CFScript.
Flash Remoting | In client-side ActionScript, you use the NetServices functions to invoke component methods. | See Using the Flash Remoting service.
Web services | You use the cfinvoke tag and CFScript to consume web services in ColdFusion. | See Using Web Services.

Note: To restrict component method invocation, you use the access and roles attributes of the cffunction tag. For more information, see Using web server authentication.

Note: To invoke components within the component method definition, you use th cfinvoke tag with its method attribute. In CFScript, you use the method name in standard function syntax, such as methodName().


Invoking component methods using the cfinvoke tag

In ColdFusion pages or components, use the cfinvoke tag to invoke component methods. You can place multiple cfinvoke tags in a ColdFusion page to invoke multiple component methods.

Syntax

<cfinvoke component="componentName" method="methodName"
returnVariable="variableName" argumentCollection="argumentStruct">

The following table displays the tag attribute, data type, and description:

Attribute | Type | Required | Description | For more information
component | string | yes | Name of component |
method | string | yes | Name of component method | See Invoking component methods using the cfinvoke tag.
returnVariable | string | no | Creates a variable by the name entered and assigns the component method results into that variable | See Returning values from component methods.
argumentCollection | structure | no | Passes structure to component method as parameters | See Passing parameters to component methods

To invoke a component method using the cfinvoke tag:

  1. Open the tellTime.cfc file, and modify the code so that it appears as follows:
    2. <cfcomponent>
   <cffunction name="getLocalTime">
       <cfscript>
         serverTime=now();
         localStruct=structNew();
         localStruct.Hour=DatePart("h", serverTime);
         localStruct.Minute=DatePart("n", serverTime);
      </cfscript>
      <cfoutput>#localStruct.Hour#:#localStruct.Minute#</cfoutput>
   </cffunction>
   <cffunction name="getUTCTime">
      <cfscript>
         serverTime=now();
         utcTime=GetTimeZoneInfo();
         utcStruct=structNew();
         utcStruct.Hour=DatePart("h", serverTime);
         utcStruct.Minute=DatePart("n", serverTime);
         utcStruct.Hour=utcStruct.Hour + utcTime.utcHourOffSet;
         utcStruct.Minute=utcStruct.Minute + utcTime.utcMinuteOffSet;
      </cfscript>
      <cfoutput>#utcStruct.Hour#:#utcStruct.Minute#</cfoutput>
   </cffunction>
</cfcomponent>

The example defines two component methods, getLocalTime and getUTCTime.
  2. Create a new ColdFusion page, and save it as timeDisplay.cfm in the same directory as the tellTime component.
  3. Modify the ColdFusion page so that is appears as follows:
    4. <h3>Time Display Page</h3>
<b>Server's Local Time:</b>
<cfinvoke component="tellTime" method="getLocalTime"><br>
<b>Calculated UTC Time:</b>
<cfinvoke component="tellTime" method="getUTCTime">

Using the cfinvoke tag, the example invokes the getLocalTime and getUTCTime component methods.
  4. The following figure shows the results when you execute timeDisplay.cfm in a web browser:

    5. This is a picture of the feature being described.


Invoking component methods using the cfobject tag

To separate the instantiation of the component and the invocation of the component method, use the cfobject tag. First, use the cfobject tag to instantiate the component and assign the component to a variable. For example:

<cfobject name="tellTimeComp" component="tellTime">

To invoke component methods, use the cfinvoke tag. The cfinvoke tag’s name attribute references the variable name in the cfobject tag’s name attribute. For example:

<cfobject name="tellTimeComp" component="tellTime">
<cfinvoke component="#tellTimeComp#" method="getLocalTime">
<cfinvoke component="#tellTimeComp#" method="getUTCTime">


Invoking component methods using a URL

To invoke a component method using a URL, you must append the method name to the URL in the standard URL query-string, name-value syntax. You can only invoke one component method per URL request. For example:

http://localhost:8500/tellTime.cfc?method=getLocalTime

Note: To use URL invocation, you must set the cffunction tag’s access attribute to remote.


Invoking component methods using a form

To invoke a method using a ColdFusion or an HTML form, you must enter the file path to the ColdFusion component in the action attribute and the method name as a form variable that is submitted.

Note: To use form invocation, you must set the cffunction tag’s access attribute to remote.

To invoke component methods using a form:

  1. Open timeDisplay.cfm, and modify the page so that it appears as follows:
    2. <h3>Time Display Page</h3>
<p>Make your selection and press the Got the time? button:</p>
<cfform action="tellTime.cfc" method="POST">
<cfselect name="Method" required="Yes">
   <option value="getLocalTime" selected>Local Time</option>
   <option value="getUTCTime">UTC Time</option>
</cfselect>
<input type="submit" value="Got the time?">
</cfform>

In the example, the cfform tag’s action attribute points toward the tellTime component file. The cfselect statement passes the component method name.
  2. Save your work.
  3. Start your web browser, and browse to the following URL:
    4. http://localhost:8500/timeDisplay.cfm

The following figure shows the results:

  This is a picture of the feature being described.

Make a selection from the drop-down box, and click the Got the Time? button. Depending on your selection, the server’s local or UTC time displays.


Invoking component methods with CFScript

To invoke a a component method using CFScript, use the createObject function or cfobject tag to instantiate the component. After you instantiate the component, you use normal function syntax to invoke component methods. For example:

<!--- instantiate once and reuse the instance--->
<cfscript>
   tellTimeCFC=createObject("component","tellTime");
</cfscript>
<b>Server's Local Time:</b>
   <cfscript>
      tellTimeCFC.getLocalTime();
</cfscript>
<br>
<b>Calculated UTC Time:</b>
<cfscript>
   tellTimeCFC.getUTCTime();
</cfscript

In the example, the two CFScript statements assign the tellTimeCFC variable to the tellTime component using the createObject function. Next, you use normal function syntax to invoke the component method.


Passing parameters to component methods

To perform conditional processing in ColdFusion components based on data sent from the client, you pass parameters to component methods. In ColdFusion applications, parameters typically consist of user name and password information, session state data, keywords for database queries, and so on.

To pass parameters in ColdFusion components, follow these steps:

  1. Define the parameter in the component method definition using the cfargument tag. For more information, see Defining the parameter in the component method definition.
  2. Choose your parameter-passing technique. Use the parameter-passing technique best suited for your client type. For more information, see Choosing a parameter-passing technique.


Defining the parameter in the component method definition

In the component method, you create parameter definitions using the cfargument tag within the component method definition. You define multiple parameter with multiple cfargument tags. To access the parameter values in the component method definition, you use structure- or array-like notation with the argument variable.

Syntax

<cfargument name="parameterName" type="dataType" required="true/false"
default="defaultValue">

The following table displays the tag attribute, data type, and description:

Attribute | Type | Required | Description
name | string | yes | Name of parameter
type | data type | no | Validates all valid data types
required | Boolean | no | Specifies whether the parameter is required to execute the component method
argumentCollection | all types | no | Provides a default value when a parameter is not passed

Also, if the required attribute is not set to true, you can specify a default value for the parameter value using the default attribute. The following example defines two parameters and references the parameter values in the component method definition.

Note: For the following procedures to work, you must have the example applications installed with ColdFusion. For more information, see the CFML Reference.

To define parameters in the component method definition:

  1. Create a new component, and save it as corpQuery.cfc in a directory under your web root directory.
  2. Modify the code in corpQuery.cfc so that it appears as follows:
    3. <cfcomponent>
   <cffunction name="getEmp">
      <cfargument name="lastName" required="true">
       <cfquery name="empQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT LASTNAME, FIRSTNAME, EMAIL
          FROM tblEmployees
         WHERE LASTNAME LIKE '#arguments.lastName#'
       </cfquery>
       <cfoutput>Results filtered by #arguments.lastName#:</cfoutput><br>
       <cfdump var=#empQuery#>
   </cffunction>
   <cffunction name="getCat">
   <cfargument name="cost" required="true">
      <cfquery name="catQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT ItemName, ItemDescription, ItemCost
          FROM tblItems
         WHERE ItemCost <= #arguments.cost#
       </cfquery>
       <cfoutput>Results filtered by #arguments.cost#:</cfoutput><br>
       <cfdump var=#catQuery#>
   </cffunction>
</cfcomponent>

In the example, the cfargument tag’s name attribute defines the parameter’s name. The required attribute indicates that the parameter is required or an exception will be thrown. The arguments variable scope provides access to the parameter values.

    Note: You can also reference multiple parameter values using array- and structure-like syntax. For example, arguments.cost is the same as argument[1]. Array and structure-like notation also lets you loop over multiple parameters. In addition, you can access arguments directly using pound signs, such as #cost#.
  3. Save your work.


Choosing a parameter-passing technique

Like ColdFusion pages, you can pass parameters using a URL or the HTTP GET and POST form methods with ColdFusion components. Components also accept passing parameters using the cfinvoke tag.

The following table describes your parameter-passing options:

Parameter Type | Description | For more information
cfinvoke tag | Specify the parameters as cfinvoke tag attributes or the argumentsCollection attribute. | See Passing parameters using the cfinvoke tag.
cfinvokeargument tag | Specify parameter name and values using the cfinvokeargument tag. | See Passing parameters using the cfinvokeargument tag.
URL | Specify the parameters in the standard URL query-string, name-value pair syntax. | See Passing parameters using a URL.
Form | Specify the parameters as form input values. | See Passing parameters using a form.
CFScript | Specify the parameters as ordered arguments or named arguments. | See Passing parameters using CFScript.
Flash Remoting | Specify the parameters In client-side ActionScript. | See Using the Flash Remoting service.
Web services | Specify the parameters as cfinvoke tag attributes or the argumentsCollection attribute. | See Using Web Services.


Passing parameters using the cfinvoke tag

You can pass a single or multiple parameters in one cfinvoke tag as tag attribute name-value pairs. The following example passes a single parameter:

<cfinvoke component="authQuery" method="getAuth" lastName=session.username>

In the example, the lastName attribute passes the value of the session scope variable to the component method. To pass multiple parameters, use an attribute name-value pair for each parameter. For example:

<cfinvoke component="authQuery" method="getAuthSecure"
lastName=session.username password=#url.password#>

In the example, the parameters are passed as the lastName and password attributes. Notice that different variable scopes are used in the attribute values.

Note: The cfinvoke tag attribute names are reserved and cannot be used for parameter names. The reserved attribute names are component, method, argumentCollection, and returnVariable. For more information, see the CFML Reference.

If you save attributes to a structure, you can directly pass the structure using the cfinvoke tag’s argumentCollection attribute.

The following example invokes a component that performs simple addition and subtraction:

<cfscript>
   exampleStruct = StructNew();
   exampleStruct[1] = 1;
   exampleStruct[2] = 2;
</cfscript>
<cfinvoke component="arithCFC" method="add" argumentCollection=exampleStruct>

This example passes two parameters to the component method as a structure. Notice the use of the argumentCollection attribute of the cfinvoke tag.


Passing parameters using the cfinvokeargument tag

To pass parameters independently of the cfinvoke tag, use the cfinvokeargument tag. Using the cfinvokergument tag, for example, you can build conditional processing that passes a different parameter based on user input.

Syntax

<cfinvokeargument name="parameterName" value="anyValue">

The following table displays the tag attribute, data type, and description:

Attribute | Type | Required | Description
name | string | yes | Name of parameter
value | all types | yes | Value of parameter

The following example invokes the corpQuery component:

<cfinvoke component="corpQuery" method="getEmp">
<cfinvokeargument name="lastName" value="camden">

Notice that the cfinvokeargument tag passes the lastName parameter to the component method.

Note: For more information about parameter precedence, see the CFML Reference book.


Passing parameters using a URL

To pass parameters to component methods using a URL, append the parameters to the URL in standard URL query-string, name-value pair syntax. For example:

http://localhost:8500/corpQuery.cfc?method=getEmp&lastName=camden

To pass multiple parameters within a URL, use the ampersand (&) character to delimit the name-value pairs. Here is an example:

http://localhost:8500/
corpQuerySecure.cfc?method=getAuth&store=women&dept=shoes

Note: Due to security concerns, Macromedia strongly recommends that you do not pass sensitive information over the web using URL strings. Potentially sensitive information includes all personal user information, including passwords, addresses, telephone numbers, and so on.


Passing parameters using a form

To pass parameters to components using an HTML or ColdFusion form, the names of the client input controls must match the names of the parameter definition in the component file.

To pass parameters using a form:

  1. Open the corpFind.cfm file and modify the code so that it appears as follows:
    2. <h2>Find People and Products</h2>
<form action="components/corpQuery.cfc" method="post">
   <p>Enter employee's last Name:</p>
   <input type="Text" name="lastName">
   <input type="Hidden" name="method" value="getEmp">
   <input type="Submit" title="Submit Query"><br>
</form>
<form action="components/corpQuery.cfc" method="post">
   <p>Enter maximum product price:</p>
   <input type="Text" name="cost">
   <input type="Hidden" name="method" value="getCat">
   <input type="Submit" title="Submit Query">
</form>

In the example, the form tag action attribute points to the corpQuery component. The input tags invoke the component method.
  2. Open corpQuery.cfc and add access="remote" to each cffunction tag, as the following example shows:
    3. <cfcomponent>
   <cffunction name="getEmp" access="remote">
      <cfargument name="lastName" required="true">
       <cfquery name="empQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT LASTNAME, FIRSTNAME, EMAIL
          FROM tblEmployees
         WHERE LASTNAME LIKE '#arguments.lastName#'
       </cfquery>
       <cfoutput>Results filtered by #arguments.lastName#:</cfoutput><br>
       <cfdump var=#empQuery#>
   </cffunction>
   <cffunction name="getCat" access="remote">
   <cfargument name="cost" required="true">
      <cfquery name="catQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT ItemName, ItemDescription, ItemCost
          FROM tblItems
         WHERE ItemCost <= #arguments.cost#
       </cfquery>
       <cfoutput>Results filtered by #arguments.cost#:</cfoutput><br>
       <cfdump var=#catQuery#>
   </cffunction>
</cfcomponent>

In this example, the cffunction access attribute lets remote clients, such as web browsers and Flash applications, to access component methods.
  3. Save your work.
  4. Open a web browser and enter the following URL:
    5. http://localhost/corpFind.cfm

The following figure shows the results:

  This is a picture of the feature being described.

Depending on what you enter, after you click the Submit Query button, the web browser displays the results as shown in the following figure:

  This is a picture of the feature being described.


Passing parameters using CFScript

The following example instantiates a component, invokes the getAuth component method in three different ways, and passes parameters in each method invocation:

<cfscript>
   corpQCFC = createObject("component", "corpSecurity");
   corpQCFC.getAuth(username="skippy" password="dippy");
   tempStruct = structNew();
   tempStruct.username = "skippy"
   tempStruct.password = "dippy"
   corpQCFC.getAuth(argumentsCollention = tempStruct);
   corpQCFC.getAuth("skippy", "dippy");
</cfscript>


Returning values from component methods

In the component method definition, you return the results to the client using the cfreturn tag. The equavilent to the return CFScript statement, the cfreturn tag only accepts one variable to return at a time. Therefore, if you want to return more than one result value at a time, populate a structure with name-value pairs and return the structure using the cfreturn tag.

To access the result values returned to the client, use the variable scope specified as the value of the cfinvoke tag’s returnVariable attribute.


Returning component method results to the client

To return component method results to the client, use the cfreturn tag in the component method definition. You can pass values of all data types, including strings, integers, arrays, and structures.

To prepare the component method definition to return a value:

  1. Open the corpQuery.cfc file, and modify the code so that it appears as follows:
    2. <cfcomponent>
   <cffunction name="getEmp">
       <cfquery name="empQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT LASTNAME, FIRSTNAME, EMAIL
          FROM tblEmployees
       </cfquery>
       <cfreturn empQuery>
   </cffunction>
   <cffunction name="getCat">
      <cfquery name="catQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT ItemName, ItemDescription, ItemCost
          FROM tblItems
       </cfquery>
       <cfreturn catQuery>
   </cffunction>
</cfcomponent>

In the example, the cfreturn tags return the query objects created by the component methods.
  2. Save your work.
  3. Open the corpFind.cfm file, and modify the code so that it appears as follows:
    4. <cfinvoke component="corpQuery" method="getEmp" returnVariable="empResult">
<cfdump var=#empResult#>

In the example, the cfinvoke tag’s returnVariable attribute specifies the variable scope name that holds the component method results. The cfdump tag displays the contents of the empResult variable.
  4. Open a web browser and browse to the following URL:
    5. http://localhost/corpFind.cfm

The following figure shows the results:

  This is a picture of the feature being described.


Using advanced ColdFusion component functionality

Beyond basic component functionality, ColdFusion components offer advanced functionality to streamline application development, deployment, and extensibility. The following table displays advanced component functionality:

Feature | Description | For more information
Component method security | Using the roles and access attributes of the cffunciton tag, you build component method-level security measures. | See Building secure ColdFusion components.
Component packages | Using component packages, you avoid possible naming conflicts with components. | See Using component packages.
Component inheritance | Using the extends attribute of the cfcomponent tag, you import another component’s methods and properties. | See Using component inheritance.
Component introspection | Using component metadata, you can describe component functionality programmatically. | See Using component metadata.


Building secure ColdFusion components

To restrict access to component methods, ColdFusion components use the following security features:

  1. Web server basic authentication -- For more information, see Using web server authentication.
  2. Application security -- For more information, see Using ColdFusion application security.
  3. Role-based security -- For more information, see Using role-based security.
  4. Programmtic security -- For more information, see Using programmtic security.


Using web server authentication

The majority of web servers allow directory access protection using basic authentication. When a client tries to access one of the resources under a protected directory and is not properly authenticated, the server automatically sends back a authentication challenge to the web browser. The web browser shows a login dialog box.

When you enter your authentication information, the web browser authenticates the information to the web server. If the authentication passes, the web browser caches the authentication data while the browser window is open and every subsequent request to the web server sends the same authentication data

ColdFusion developers can use the authentication information for ColdFusion resources, such as ColdFusion pages or components, in the appropriate application.cfm file, as the following example shows:

<cflogin>
   <cfif IsDefined( “cflogin” )>
      <cfif cflogin.name eq “admin”>
         <cfset roles = “user,admin”>
      <cfelse>
         <cfset roles = “user”>
      </cfif>
      <cfloginuser name = ”#cflogin.name#”
      password = ”#cflogin.password#”
      roles = “#roles#” />
   <cfelse>
      <!--- this should never happen --->
      <h4>Authentication data is missing.</h4>
      Try to reload the page or contact the site administrator.
      <cfabort>
   </cfif>
</cflogin>


Using ColdFusion application security

You can use the previous example with minor modification to include the login challenge in the application.cfm file as well. You can create an HTML form page that passes authentication information to ColdFusion, or you can return the access-denied 401 infromation back to the web browser.

The following example illustrates an authentication challenge by generating and HTML page with a login form. The login form sends two form fields, j_username and j_password, to ColdFusion, which are automatically detected by the cflogin tag.

<cflogin>
   <cfif IsDefined( "cflogin" )>
      <cfif cflogin.name eq "admin" and cflogin.password eq "p1">
         <cfset roles = "user,admin">
         <cfelseif cflogin.name eq "user" and cflogin.password eq "p2">
         <cfset roles = "user">
      </cfif>
   </cfif>
   <cfif IsDefined( "roles" )>
      <cfloginuser name="#cflogin.name#"
         password="#cflogin.password#"
         roles="#roles#">
   <cfelse>
      <!--- authentication failed – generate the login form --->
      <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
      <html><head><title>Application Log In</title></head>
      <body>
         <form action="" method="post">
            <pre>
               username: <input type="text" name="j_username">
               password: <input type="password" name="j_password">
               <input type="submit" value="log in">
            </pre>
         </form>
      </body>
      </html>
      <cfabort>
   </cfif>
</cflogin>

When you return a 401 access denied response, the browser automatically displays a login dialog box. When the user enters his or her login dialog, the authentication parameters are passed in the request header and are detected by the cflogin tag, as shown in the following example:

<cflogin>
   <cfif IsDefined( "cflogin" )>
      <cfif cflogin.name eq "admin" and cflogin.password eq "p1">
         <cfset roles = "user,admin">
      <cfelseif cflogin.name eq "user" and cflogin.password eq "p2">
         <cfset roles = "user">
      </cfif>
   </cfif>
   <cfif IsDefined( "roles" )>
      <cfloginuser name="#cflogin.name#" password="#cflogin.password#"
roles="#roles#">
   <cfelse>
      <!--- authentication failed – send back 401 --->
      <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
      <cfheader statuscode="401">
      <cfheader name="WWW-Authenticate" value="Basic realm=""MySecurity""">
      <cfoutput>Not authorized</cfoutput>
      <cfabort>
   </cfif>
</cflogin>

The security realm name can be used to bind multiple directories together. If application.cfm files located in those directories use the same realm name, only a single login is required to access resources in those directories. However, each application.cfm files can establish different roles for a user.


Using role-based security

Access to a particular method in component can be restricted using roles security. When a component method is restricted to one or more roles using the roles attribute of the cffunction tag, users must fall into one of the security roles., as shown in the following example:

<cffunction name=”foo” roles=”admin,moderator”>
   . . .
</cffunction>

Use the cfloginuser tag to establish the security roles. The cflogin tag caches the authetication information.When a user tries to invoke a method that he or she is not authorized to invoke, an exception is returned. For more information, see Securing Applications.


Using programmtic security

In the component method definition, you can protect resources using the same CFML constructs as ColdFusion pages. For example, the IsUserInRole function determines whether the user is authenticated in a particular sercurity role:

<cffunction name=”foo”>
   <cfif IsUserInRole(“admin”)>
      … do stuff allowed for admin
   <cfelseif IsUserInRole(“user”)>
      … do stuff allowed for user
   <cfelse>
      <cfoutput>unauthorized access</cfoutput>
      <cfabort>
   </cfif>
</cffunction>


Using component packages

Components invoked by ColdFusion pages do not need to be in the same directory as the client ColdFusion page or component, Web page, or Flash movie. In fact, components can reside in any folder under the web root directory or virtual directory mapping in the web server, in a directory under a ColdFusion mapping, or the custom tag roots.

Components stored in the same directory are members of a component package. Component packages help prevent naming conflicts and facilitate easy component deployment.

To invoke a packaged component method using the cfinvoke tag:

  1. In your web root directory, create a folder named appResources.
  2. In the appResources directory, create a folder named components.
  3. Move tellTime.cfc and utcTimeFormatted.cfm to the components directory.
  4. Create a new ColdFusion page and save it in your web root as timeDisplay.cfm.
  5. Modify the page so that is appears as follows:
    6. <h3>Time Display Page</h3>
<b>Server's Local Time:</b>
<cfinvoke component="appResources.components.tellTime"
method="getLocalTime"><br>
<b>Calculated UTC Time:</b>
<cfinvoke component="appResources.components.tellTime"
method="getUTCTime">

You use dot syntax to navigate directory structures. Prefix the directory name before the component name.
  6. Save your work.

The following example shows a CFScript invocation:

<cfscript>
helloCFC = createObject("component", "appResources.components.catQuery");
helloCFC.getSaleItems();
</cfscript>

The following example shows an URL invocation:

http://localhost/appResources/components/catQuery.cfc?method=getSalesItems


Saving ColdFusion components

The following table contains the locations in which you can save component files and the available accessibility options from each location:

 | Web root | ColdFusion mappings | Custom tag roots | Current directory
URL | Yes | Yes | No | Yes
Form | Yes | No | No | Yes
Flash Remoting | Yes | No | No | Yes
Web services | Yes | No | No | Yes
Local | Yes | Yes | Yes | Yes

Note: ColdFusion mappings and custom tag roots can exist within the web root. If so, they are accessible to remote requests, including URL, form, Flash Remoting, and web service invocation.


Naming ColdFusion components

Establishing a descriptive naming conventionIt is a good practice, especially if the components will be installed as a part of packaged application. Like the common Java naming convention, you can reserve the order of your domain name, continue with application name, and so on, as the following example shows:

com.mycompany.catalog.product.saw

When you refer to a component using the fully qualified name, ColdFusion looks for the component in the following order:

  • ColdFusion attempts to resolve the physical path from the request, such as /com/mycompany/catalog/product/saw.cfc, to a component file located in directories under the web root or directories under ColdFusion mappings.
  • Otherwise, ColdFusion attempts to resolve the physical path in the custom tag root, such as {customTagRoot}/com/mycompany/catalog/product/saw.cfc,.

When a component is invoked using any of the interfaces mentioned previously, ColdFusion generates the key name in the component metadata structure in the following order:

  • If a component file exists in a directory accessible by ColdFusion mappings, use GetRealPath function to evaluate the component phyiscal path. The URI path string after .cfc and the leading slash is removed, and all slashes are replaced with dots.
  • Otherwise, ColdFusion loops over the custom tag roots looking for the ancestor directory of the component. The physical path string after the root path and file extension are removed, and all slashes are replaced with dots
  • Otherwise, ColdFusion uses the file name without the extension as the component name.


Using component inheritance

Component inheritance lets you import component methods and properties from one component into another component. In addition, inherited components also share any component methods or properties that they inherit from other components.

When using component inheritance, inheritance should define an "is a" relationship between components. For example, a component named president.cfc inherits the component methods of manager.cfm, which inherits its methods from employee.cfc. In other words, president.cfc is a manager.cfc. The manager.cfc is a employee.cfc. In turn, president.cfc is a employee.cfc

To use component inheritance:

  1. Open the corpQuery.cfc file, and modify the code so that it appears as follows:
    2. <cfcomponent extends="appResources.components.tellTime">
   <cffunction name="getEmp" returnType="query">
   <cfargument name="lastName" required="yes">
       <cfquery name="empQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT LASTNAME, FIRSTNAME, EMAIL
          FROM tblEmployees
         WHERE LASTNAME LIKE '#arguments.lastName#'
       </cfquery>
       <cfif empQuery.recordcount LT 1>
          <cfthrow type="noQueryResult"
            message="No results were found. Please try again.">
         <cfelse>
              <cfreturn empQuery>
         </cfif>
   </cffunction>
   <cffunction name="getCat" returnType="query">
      <cfquery name="catQuery" datasource="ExampleApps" dbtype="ODBC">
          SELECT ItemName, ItemDescription, ItemCost
          FROM tblItems
       </cfquery>
       <cfif #getCat.recordcount# LT 1>
          <cfthrow type="noQueryResult"
            message="No results were found. Please try again.">
       <cfelse>
          <cfreturn catQuery>
       </cfif>
   </cffunction>
</cfcomponent>

In the example, the cfcomponent tag’s extends attribute points to the tellTime component.
  2. Save your work.
  3. Create a new ColdFusion page, and save it as inherit.cfm in your web root directory.
  4. Modify the code in the inherit.cfm file so that it appears as follows:
    5. <cfinvoke component="corpQuery" method="getEmp" lastName="gilson">
<cfinvoke component="corpQuery" method="getLocalTime">
  5. Save your work.

When you execute the inherit.cfm file, the getLocalTime component method executes like the getEmp component method.


Using component metadata

When you access a ColdFusion component directly with a web browser without specifying a component method, the following chain of events occurs:

  • The request is redirected to CFCExplorer.cfc, which is located in the [webroot]\CFIDE\componentutils directory.
  • The CFCExplorer component prompts users for the ColdFusion RDS password.
  • The CFCExplorer renders an HTML description. For example, when the corpQuery component is accessed directly by a web browser, it produces the following results:

The following figure shows the HTML description for the corpQuery component:

This is a picture of the feature being described.

As you can see in the description that displays in the web browser, components list the methods that you build. Development teams can use a component’s automatically generated description as always up-to-date API reference information.

In addition, you can use the cfcToMCDL and cfcToHTML component methods of utils.cfc, which is located in the [webroot]\CFIDE\componentutils directory.

You can also browse the components available in ColdFusion using the Component Browser, which is located at [webroot]\CFIDE\componentutils\componentdoc.cfm. The following figure shows the Component browser

:

This is a picture of the feature being described.

Note: To access the Component Browser in a virtual directory, you must add the virtual directory to the ColdFusion mappings.
Previous


Building Custom CFXAPI Tags

Sometimes, the best approach to application development is to develop elements of your application by building executables to run with ColdFusion. Perhaps the application requirements go beyond what is currently feasible in CFML. Perhaps you can improve application performance for certain types of processing. Or, you have existing code that already solves an application problem and you want to incorporate it into your ColdFusion application.

To meet these types of requirements, you can use the ColdFusion Extension Application Programming Interface (CFX API) to develop custom ColdFusion tags. This chapter documents custom tag development using Java or C++.

Contents
  • What are CFX tags?
  • Before you begin developing CFX tags in Java
  • Writing a Java CFX tag
  • ZipBrowser example
  • Approaches to Debugging Java CFX tags
  • Developing CFX tags in C++
Next


What are CFX tags?

ColdFusion Extension (CFX) tags are custom tags written against the ColdFusion Extension Application Programming Interface. Generally, you create a CFX tag if you want to do something that is not possible in CFML, or if you want to improve the performance of a repetitive task.

One common use of CFX tags is to incorporate existing application functionality into a ColdFusion application. That means if you already have the code available, CFX tags make it easy to use it in your application.

CFX tags can do the following:

  • Handle any number of custom attributes.
  • Use and manipulate ColdFusion queries for custom formatting.
  • Generate ColdFusion queries for interfacing with non-ODBC based information sources.
  • Dynamically generate HTML to be returned to the client.
  • Set variables within the ColdFusion application page from which they are called.
  • Throw exceptions that result in standard ColdFusion error messages.

You can build CFX tags using C++ or Java.

Note: ColdFusion provides several different techniques to create reusable code, including custom tags. For information on all of these techniques, see Reusing Code in ColdFusion Pages.


Before you begin developing CFX tags in Java

Before you begin developing CFX tags in Java, you must configure your Java development environment. Also, you might want to take a look at some examples before creating your own CFX tags. This section contains information about examples and how to configure your development environment.


Sample Java CFX tags

Before you begin developing a CFX tag in Java, you might want to study sample CFX tags. You can find the Java source files for the examples on Windows in the cfx\java\distrib\examples subdirectory of the main installation directory. On UNIX systems, the files are located in the cfx/java/examples directory. The following table describes the example tags:

Example | Action | Demonstrates
HelloColdFusion | Prints a personalized greeting. | The minimal implementation required to create a CFX tag.
ZipBrowser | Retrieves the contents of a zip archive. | How to generate a ColdFusion query and return it to the calling page.
ServerDateTime | Retrieves the date and time from a network server. | Attribute validation, using numeric attributes, and setting variables within the calling page.
OutputQuery | Returns a ColdFusion query in an HTML table. | How to handle a ColdFusion query as input, throw exceptions, and generate dynamic output.
HelloWorldGraphic | Generates a “Hello World!” graphic in JPEG format. | How to dynamically create and return graphics from a Java CFX tag.


Setting up your development environment to develop CFX tags in Java

You can use a wide range of Java development environments, including the Java Development Kit (JDK) v 1.3.1 from Sun, to build Java CFX tags. You can download the JDK from Sun .

Macromedia recommends that you use one of the commercial Java IDEs, such as Dreamweaver MX, that provide an integrated environment for development, debugging, project management, and access to documentation.


Configuring the class path

To configure your development environment to build Java CFX tags, you must ensure that the supporting classes are visible to your Java compiler. These classes are located in the cfx.jar archive, located in the lib subdirectory of your ColdFusion installation directory. Consult your Java development tool documentation to determine how to configure the compiler class path for your particular environment.

The lib directory created by the ColdFusion setup program serves two purposes:

  • It contains the supporting classes required for developing and deploying Java CFX tags. This is the com.allaire.cfx package located in the cfx.jar archive.
  • It supports a feature that allows Java CFX tags located in the directory to be reloaded every time they are changed. Although this is not the default behavior for other Java classes, this behavior is very useful during an iterative development and testing cycle.

When you create new Java CFX tags, you should develop them in the web_root/WEB-INF/classes directory. Doing this simplifies your development, debugging, and testing processes.

After you finish with development and testing, you can deploy your Java CFX tag anywhere on the class path visible to the ColdFusion embedded JVM. For more details on customizing the class path, see Customizing and Configuring Java.


Customizing and Configuring Java

Use the JVM and Java Settings page on the ColdFusion Administrator Server tab to customize your Java development environment, such as by customizing the class path and Java system properties, or specifying an alternate JVM. For more information, see the ColdFusion Administrator’s online help.


Writing a Java CFX tag

To create a Java CFX tag, create a class that implements the CustomTag interface. This interface contains one method, processRequest, which is passed Request and Response objects that are then used to do the work of the tag.

The example in the following procedure creates a very simple Java CFX tag named cfx_MyHelloColdFusion that writes a text string back to the calling page.

To create a Java CFX tag:

  1. Create a new source file in your editor with the following code:
    2. import com.allaire.cfx.* ;

public class MyHelloColdFusion implements CustomTag
{
   public void processRequest( Request request, Response response )
      throws Exception
   {
      String strName = request.getAttribute( "NAME" ) ;
      response.write( "Hello, " + strName ) ;
   }
}
  2. Save the file as MyHelloColdFusion.java in the web_root/WEB_INF/classes directory.
  3. Compile the java source file into a class file using the Java compiler. If you are using the command-line tools bundled with the JDK, use the following command line, which you execute from within the classes directory:
    4. javac -classpath cf_root\lib\cfx.jar MyHelloColdFusion.java

    Note: The previous command works only if the Java compiler (javac.exe) is in your path. If it is not in your path, specify the fully qualified path; for example, c:\jdk1.3.1_01\bin\javac on Windows or /usr/java/bin/javac on UNIX.

If you receive errors during compilation, check the source code to make sure you entered it correctly. If no errors occur, you successfully wrote your first Java CFX tag. For information on using your new tag in a ColdFusion page, see Calling the CFX tag from a ColdFusion page.


Calling the CFX tag from a ColdFusion page

You call Java CFX tags from within ColdFusion pages by using the name of the CFX tag that is registered on the ColdFusion Administrator CFX tags page. This name should be the prefix cfx_ followed by the class name (without the .class extension).

To register a Java CFX tag in the ColdFusion Administrator:

  1. On the ColdFusion Administrator Server tab, select Extensions > CFX Tags to open the CFX Tags page.
  2. Click Register Java CFX.
  3. Enter the tag name (for example, cfx_MyHelloColdFusion).
  4. Enter the class name without the .class extension (for example, MyHelloColdFusion).
  5. (Optional) Enter a description.
  6. Click Submit.

You can now call the tag from a ColdFusion page.

To call a CFX tag from a ColdFusion page:

  1. Create a CFML page in your editor with the following content to call the HelloColdFusion custom tag:
    2. <html>
<body>
   <cfx_MyHelloColdFusion NAME="Les">
</body>
</html>
  2. Save the file in a directory configured to serve ColdFusion pages. For example, you can save the file as C:\inetpub\wwwroot\cfdocs\testjavacfx.cfm on Windows or /home/docroot/cfdocs/testjavacfx.cfm on UNIX.
  3. If you have not already done so, register the CFX tag in the ColdFusion Administrator (see Registering CFX tags).
  4. Request the page from your browser using the appropriate URL; for example:

    5. http://localhost/cfdocs/testjavacfx.cfm

ColdFusion processes the page and returns a page that displays the text “Hello, Les.” If an error is returned instead, check the source code to make sure you have entered it correctly.

To delete a CFX tag in the ColdFusion Administrator:

  1. On the ColdFusion Administrator Server tab, select Extensions > CFX Tags to open the CFX Tags page.
  2. For the tag you want to delete, click the Delete icon in the Controls column of the Registered CFX Tags list.


Processing requests

Implementing a Java CFX tag requires interaction with the Request and Response objects passed to the processRequest method. In addition, CFX tags that need to work with ColdFusion queries also interface with the Query object. The com.allaire.cfx package, located in the lib/cfx.jar archive, contains the Request, Response, and Query objects.

This section provides an overview of these object types. For a complete description of these object types, see CFML Reference.

For a complete example Java CFX tag that uses Request, Response, and Query objects, see ZipBrowser example.


Request object

The Request object is passed to the processRequest method of the CustomTag interface. The following table lists the methods of the Request object for retrieving attributes, including queries, passed to the tag and for reading global tag settings.

Method | Description
attributeExists | Checks whether the attribute was passed to this tag.
getAttribute | Retrieves the value of the passed attribute.
getIntAttribute | Retrieves the value of the passed attribute as an integer.
getAttributeList | Retrieves a list of all attributes passed to the tag.
getQuery | Retrieves the query that was passed to this tag, if any.
getSetting | Retrieves the value of a global custom tag setting.
debug | Checks whether the tag contains the debug attribute.

For detailed reference information on each of these interfaces, see the CFML Reference.


Response object

The Response object is passed to the processRequest method of the CustomTag interface. The following table lists the methods of the Response object for writing output, generating queries, and setting variables within the calling page.

Method
Description
write
Outputs text to the calling page.
setVariable
Sets a variable in the calling page.
addQuery
Adds a query to the calling page.
writeDebug
Outputs text to the debug stream.

For detailed reference information on each of these interfaces, see the CFML Reference.


Query object

The Query object provides an interface for working with ColdFusion queries. The following table lists the methods of the Query object for retrieving name, row count, and column names and methods for getting and setting data elements.

Method
Description
getName
Retrieves the name of the query.
getRowCount
Retrieves the number of rows in the query.
getColumns
Retrieves the names of the query columns.
getData
Retrieves a data element from the query.
addRows
Adds a new row to the query.
setData
Sets a data element within the query.

For detailed reference information on each of these interfaces, see the CFML Reference.


Loading Java CFX classes

Each Java CFX class has its own associated ClassLoader that loads it and any dependent classes also located in the web_root/WEB-INF/classes directory. When Java CFX classes are reloaded after a change, a new ClassLoader is associated with the freshly loaded class. This special behavior is similar to the way Java servlets are handled by the web server and other servlet engines, and is required in order to implement automatic class reloading.

However, this behavior can cause subtle problems when you are attempting to perform casts on instances of classes loaded from a different ClassLoader. The cast fails even though the objects are apparently of the same type. This is because the object was created from a different ClassLoader and therefore is not technically the same type.

To solve this problem, only perform casts to class or interface types that are loaded using the standard Java class path, that is, classes not located in the classes directory. This works because classes loaded from outside the classes directory are always loaded using the system ClassLoader, and therefore, have a consistent runtime type.


Automatic class reloading

You can determine how the server treats changed Java CFX class files by specifying the reload attribute when you use a CFX tag in your CFML page. The following table describes the allowable values for the reload attribute:

Value
Description
Auto
Automatically reload Java CFX and dependent classes within the classes directory whenever the CFX class file changes. Does not reload if a dependent class file changes but the CFX class file does not change.
Always
Always reload Java CFX and dependent classes within the classes directory. Ensures a class reload even if a dependent class changes, but the CFX class file does not change.
Never
Never reload Java CFX classes. Load them once per server lifetime.

The default value is reload="Auto". This is appropriate for most applications. Use reload="Always" during the development process, when you must ensure that you always have the latest class files, even when only a dependent class changed. Use reload="Never" to increase performance, by omitting the check for changed classes.

Note: The reload attribute applies only to class files located in the classes directory. The ColdFusion server loads classes located on the Java class path once per server lifetime. You must stop and restart ColdFusion Server to reload these classes.


Life cycle of Java CFX tags

A new instance of the Java CFX object is created for each invocation of the Java CFX tag. This means that it is safe to store per-request instance data within the members of your CustomTag object. To store data and/or objects that are accessible to all instances of your CustomTag, use static data members. If you do so, you must ensure that all accesses to the data are thread-safe.


ZipBrowser example

The following example illustrates the use of the Request, Response, and Query objects. The example uses the java.util.zip package to implement a Java CFX tag called cfx_ZipBrowser, which is a zip file browsing tag.

Note: The Java source file that implements cfx_ZipBrowser, ZipBrowser.java, is included in the cf_root\cfx\java\distrib\examples directory. Compile ZipBrowser.java to implement the tag.

The tag’s archive attribute specifies the fully qualified path of the zip archive to browse. The tag’s name attribute must specify the query to return to the calling page. The returned query contains three columns: Name, Size, and Compressed.

For example, to query an archive at the path C:\logfiles.zip for its contents and output the results, you use the following CFML code:

<cfx_ZipBrowser
      archive="C:\logfiles.zip"
      name="LogFiles" >

<cfoutput query="LogFiles">
#Name#,  #Size#, #Compressed# <BR>
</cfoutput>

The Java implementation of ZipBrowser is as follows:

import com.allaire.cfx.* ;
import java.util.Hashtable ;
import java.io.FileInputStream ;
import java.util.zip.* ;

public class ZipBrowser implements CustomTag
{
   public void processRequest( Request request, Response response )
      throws Exception
   {
      // validate that required attributes were passed
      if (  !request.attributeExists( "ARCHIVE" ) ||
            !request.attributeExists( "NAME" ) )
      {
         throw new Exception(
            "Missing attribute (ARCHIVE and NAME are both " +
            "required attributes for this tag)" ) ;
      }
    // get attribute values
      String strArchive = request.getAttribute( "ARCHIVE" ) ;
      String strName = request.getAttribute( "NAME" ) ;

   // create a query to use for returning the list of files
      String[] columns = { "Name", "Size", "Compressed" } ;
      int iName = 1, iSize = 2, iCompressed = 3 ;
      Query files = response.addQuery( strName, columns ) ;

   // read the zip file and build a query from its contents
      ZipInputStream zin =
         new ZipInputStream( new FileInputStream(strArchive) ) ;
      ZipEntry entry ;
      while ( ( entry = zin.getNextEntry()) != null )
      {
         // add a row to the results
         int iRow = files.addRow() ;

         // populate the row with data
         files.setData( iRow, iName,
            entry.getName() ) ;
         files.setData( iRow, iSize,
            String.valueOf(entry.getSize()) ) ;
         files.setData( iRow, iCompressed,
            String.valueOf(entry.getCompressedSize()) ) ;

         // finish up with entry
         zin.closeEntry() ;
      }

      // close the archive
      zin.close() ;
   }
}


Approaches to Debugging Java CFX tags

Java CFX tags are not standalone applications that run in their own process, like typical Java applications. Rather, they are created and invoked from an existing process -- ColdFusion Server. This makes debugging Java CFX tags more difficult, because you cannot use an interactive debugger to debug Java classes that have been loaded by another process.

To overcome this limitation, you can use one of two techniques:

  • Debug the CFX tag while it is running within ColdFusion Server by outputting the debug information as needed.
  • Debug the CFX tag using a Java IDE (Integrated Development Environment) that supports debugging features such as setting breakpoints, stepping through your code, and displaying variable values.
  • Debug the request in an interactive debugger offline from ColdFusion Server using the special com.allaire.cfx debugging classes.


Outputting debugging information

Before using interactive debuggers became the norm, programmers typically debugged their programs by inserting output statements in their programs to indicate information such as variable values and control paths taken. Often, when a new platform emerges, this technique comes back into vogue while programmers wait for more sophisticated debugging technology to develop for the platform.

If you need to debug a Java CFX tag while running against a live production server, this is the technique you must use. In addition to outputting debugging text using the Response.write method, you can also call your Java CFX tag with the debug="On" attribute. This attribute flags the CFX tag that the request is running in debug mode and therefore should output additional extended debugging information. For example, to call the HelloColdFusion CFX tag in debugging mode, use the following CFML code:

<cfx_HelloColdFusion name="Robert" debug="On">

To determine whether a CFX tag is invoked with the debug attribute, use the Request.debug method. To write debugging output in a special debugging block after the tag finishes executing, use the Response.writeDebug method. For information on using these methods, see the CFML Reference.


Debugging in a Java IDE

You can use a Java IDE to debug your Java CFX tags. This means you can develop your Java CFX tag and debug it in a single environment.

To use a Java IDE to debug your CFX tag:

  1. Start your IDE.
  2. In the project properties (or your IDE's project setting), make sure your CFX class is in the web_root\WEB-INF\classes directory or in the system classpath.
  3. Make sure the libraries cf_root\lib\cfx.jar and cf_root\runtime\lib\jrun.jar are included in your classpath.
  4. In your project settings, set your main class to jrunx.kernel.JRun and application parameters to -start default.
  5. Debug your application by setting breakpoints, single stepping, displaying variables, or by performing other debugging actions.


Using the debugging classes

To develop and debug Java CFX tags in isolation from the ColdFusion, you use three special debugging classes that are included in the com.allaire.cfx package. These classes lets you simulate a call to the processRequest method of your CFX tag within the context of the interactive debugger of a Java development environment. The three debugging classes are:

  • DebugRequest An implementation of the Request interface that lets you initialize the request with custom attributes, settings, and a query.
  • DebugResponse An implementation of the Response interface that lets you print the results of a request once it has completed.
  • DebugQuery An implementation of the Query interface that lets you initialize a query with a name, columns, and a data set.

To use the debugging classes:

  1. Create a main method for your Java CFX class.
  2. Within the main method, initialize a DebugRequest and DebugResponse, and a DebugQuery. Use the appropriate attributes and data for your test.
  3. Create an instance of your Java CFX tag and call its processRequest method, passing in the DebugRequest and DebugResponse objects.
  4. Call the DebugResponse.printResults method to output the results of the request, including content generated, variables set, queries created, and so on.

After you implement a main method as described previously, you can debug your Java CFX tag using an interactive, single-step debugger. Specify your Java CFX class as the main class, set breakpoints as appropriate, and begin debugging.


Debugging classes example

The following example demonstrates how to use the debugging classes:

import java.util.Hashtable ;
import com.allaire.cfx.* ;

public class OutputQuery implements CustomTag
{
   // debugger testbed for OutputQuery
   public static void main(String[] argv)
   {
      try
      {
         // initialize attributes
         Hashtable attributes = new Hashtable() ;
         attributes.put( "HEADER",  "Yes" ) ;
         attributes.put( "BORDER", "3" ) ;

         // initialize query

         String[] columns =
            { "FIRSTNAME", "LASTNAME", "TITLE" } ;

         String[][] data =  {
            { "Stephen", "Cheng", "Vice President" },
            { "Joe", "Berrey", "Intern" },
            { "Adam", "Lipinski", "Director" },
            { "Lynne", "Teague", "Developer" } }  ;

         DebugQuery query =
            new DebugQuery( "Employees", columns, data ) ;

         // create tag, process debugging request, and print results
         OutputQuery tag = new OutputQuery() ;
         DebugRequest request = new DebugRequest( attributes, query ) ;
         DebugResponse response = new DebugResponse() ;
         tag.processRequest( request, response ) ;
         response.printResults() ;
      }
      catch( Throwable e )
      {
         e.printStackTrace() ;
      }
   }

   public void processRequest( Request request ) throws Exception
   {
      // ...code for processing the request...
   }
}


Developing CFX tags in C++

The following sections provide information to help you develop CFX tags in C++.


Sample C++ CFX tags

Before you begin development of a CFX tag in C++, you might want to study the two CFX tags included with ColdFusion. These examples will help you get started working with the CFXAPI. The two example tags are as follows:

  • CFX_DIRECTORYLIST Queries a directory for the list of files it contains.
  • CFX_NTUSERDB (Windows NT only) Allows you to add and delete NT users.

On Windows NT, these tags are located in the \cfusion\cfx\examples directory. On UNIX, these tags are in cf_root/coldfusion/cfx/examples.


Setting up your C++ development environment

The following compliers generate valid CFX code for UNIX platforms:

Platform | Compiler
Solaris | Sun C++ compiler 5.0 or higher (gcc does not work)
Linux | RedHat 6.2 gcc/egcs 1.1.2 compiler
HPUX 11 | HP aCC C++ compiler

Before you can use your C++ compiler to build custom tags, you must enable the compiler to locate the CFX API header file, cfx.h. On Windows, you do this by adding the CFX API include directory to your list of global include paths. On Windows, this directory is \cfusion\cfx\include. On UNIX this directory is /opt/coldfusion/cfx/include. On UNIX, you will need -I <includepath> on your compile line (see the Makefile for the directory list example in the cfx/examples directory).


Compiling C++ CFX tags

CFX tags built on Windows and UNIX must be thread-safe. Compile CFX tags for Solaris with the -mt switch on the Sun compiler.


Locating your C++ library files on Unix

On Unix systems, your C++ library files can be in any directory as long as the directory is included in LD_LIBRARY_PATH or SHLIB_PATH (HP-UX only).


Implementing C++ CFX tags

CFX tags built in C++ use the tag request object, represented by the C++ class CCFXRequest. This object represents a request made from an application page to a custom tag. A pointer to an instance of a request object is passed to the main procedure of a custom tag. The methods available from the request object let the custom tag accomplish its work. For information about the CFX API classes and members, see the CFML Reference.


Debugging C++ CFX tags

After you configure a debugging session, you can run your custom tag from within the debugger, set breakpoints, single-step, and so on.


Debugging on Windows

You can debug custom tags within the Visual C++ environment.

To debug C++ CFX tags n Windows:

  1. Build your C++ CFX tag using the debug option.
  2. Restart ColdFusion.
  3. Start Visual C++ 6.0.
  4. Select Build >Start Debug > AttachProcess.
  5. Select jrunsvc.exe.

    6. Macromedia recommends that you shut down all other Java programs.

  6. Execute any ColdFusion page that calls the CFX tag.
  7. Use File > Open to open a file in VisualDev in which you want to set a breakpoint.
  8. Set a break-point in the CFX project. The best place is to put it in ProcessRequest(). Next time you execute the page you will hit the break point.


Registering CFX tags

To use a CFX tag in your ColdFusion applications, first register it in the Extensions, CFX Tags page in the ColdFusion Administrator.

To register a C++ CFX tag:

  1. On the ColdFusion Administrator Server tab, select Extensions > CFX Tags to open the CFX Tags page.
  2. Click Register C++ CFX.
  3. Enter the Tag name (for example, cfx_MyNewTag).
  4. If the Server Library .dll field is empty, enter the file path.
  5. Accept the default Procedure entry.
  6. Clear the Keep library loaded box while developing the tag.

    7. For improved performance, when the tag is ready for production use, you can select this option to keep the DLL in memory.

  7. (Optional) Enter a description.
  8. Click Submit.

You can now call the tag from a ColdFusion page.

To delete a CFX tag:

  1. On the ColdFusion Administrator Server tab, select Extensions > CFX Tags to open the CFX Tags page.
  2. For the tag you want to delete, click the Delete icon in the Controls column of the Registered CFX Tags list.
Previous


Designing and Optimizing a ColdFusion Application

This chapter describes the elements that make your CFML pages into an effective Internet application. It provides an overview of application elements, describes how you can structure an application on your server, and provides detailed information on using the Application.cfm file. It also describes coding methods for optimizing application efficiency.

Contents
  • About applications
  • Elements of a ColdFusion application
  • Mapping an application
  • Creating the Application.cfm page
  • Optimizing ColdFusion applications
Next


About applications

The term application can mean many things. An application can be as simple as a guest book or as sophisticated as a full Internet commerce system with catalog pages, shopping carts, and reporting.

However, an application has a specific meaning in ColdFusion. A ColdFusion application consists of one or more ColdFusion pages that work together and share a common set of resources. In particular, the application shares an application name as specified in a cfapplication tag, and all pages in the application share variables in the Application scope. What appears to a user to be a single application, for example, a company’s website, might consist of multiple ColdFusion applications.

While there are no definite rules as to how you represent your web application as a ColdFusion application or applications, the following guidelines are useful:

  • Application pages share a common general purpose. For example, a web storefront is typically a single ColdFusion application.
  • Many, but not necessarily all, pages in a ColdFusion application share data or common code elements, such as a single login mechanism.
  • Application pages share a common look and feel, often enforced by using common code elements, such as the same header and footer pages, and a common error message template.

This chapter describes the tools that ColdFusion provides to create an application, and presents information on how you can develop and optimize your application.


Elements of a ColdFusion application

Before you develop a ColdFusion application, you must determine how to structure the application and how to handle application-wide needs and issues. In particular, you must consider all of the following:

  • The overall application framework
  • Application-level settings and functions
  • Reusable application elements
  • Shared variables
  • Application security and user identification

The following sections introduce these application elements and provide references to more detailed information.


The application framework

The application framework is the overall structure of the application and how your directory structure and application pages reflect that structure. You can use a single application framework to structure multiple ColdFusion applications into a single website or Internet application. You can structure a ColdFusion application using many methodologies. For example, the FuseBox application development methodology is one popular framework for developing ColdFusion web applications. (For more information on FuseBox, see http://www.fusebox.org.)

This chapter does not provide information on how to use or develop a specific application framework. However, it does discuss how an application’s directory structure affects the application and how you can map the directory structure. For more information on mapping the application framework, see Mapping an application.

Note: For one example of an application framework, see "ColdFusion Methodologies for Content Management", available at http://www.macromedia.com/v1/handlers/index.cfm?ID=20750&method=full.


Application-level settings and functions

ColdFusion processes the following two pages, if they are available, every time it processes any page in the application:

  • The Application.cfm page is processed before each page in the application.
  • The OnRequestEnd.cfm page is processed after each page in the application.

Note: UNIX systems are case-sensitive. To ensure that your pages work on UNIX, always capitalize the A in Application.cfm and the O, R, and E in OnRequestEnd.cfm.

The Application.cfm page provides a good place to define the application. It can contain the cfapplication tag that specifies the application name, and contains code that must be processed for all pages in the application. This page defines application-level settings, functions, and features.

Application-level features can include page processing settings, default variables, data sources, style settings, and other application-level constants, and application-specific custom error pages. When defined and set on the Application.cfm page, they are available on all pages in the application.

ColdFusion applications can have application-level variables that are not in the Application scope. For example, every page in an application might have a currentPage variable that identifies the page. The Application.cfm page can set this variable in the Variables scope, so each page gets a different, local value. Because every page in the application has the variable, it can be considered to be an application-level variable, even though it is not an Application scope variable.

The OnRequestEnd.cfm page is used in fewer applications than the Application.cfm page. It lets you provide common clean-up code that gets processed after all application pages.

For more information on the Application.cfm and OnRequestEnd.cfm pages, see Creating the Application.cfm page. For information on placing these pages in the application directory structure, see Mapping an application.

Note: You can create a ColdFusion application without using Application.cfm or OnRequestEnd.cfm pages. However, it is much easier to use the Application.cfm page than to have each page in the application use a cfapplication tag and define common application elements.


Reusable application elements

ColdFusion provides a variety of reusable elements that you can use to provide commonly-used functionality and extend CFML. These elements include the following:

  • User-defined functions (UDFs)
  • CFML custom tags
  • ColdFusion components
  • CFX (ColdFusion Extension) tags
  • pages that you include using the cfinclude tag

For an overview of these elements, and information about how to choose among them, see Reusing Code in ColdFusion Pages.


Shared variables

The following ColdFusion variable scopes maintain data that lasts beyond the scope of the current HTTP request:

Variable scope | Description
Session | Variables that are available for a single client browser for a single browser session in one application.
Client | Variables that are available for a single client browser over multiple browser sessions in one application.
Application | Variables that are available to all pages in an application for all clients.
Server | Variables that are available to all applications on a server and all clients.

For more information on using these variables, including how to use locks to ensure that the data they contain remains accurate, see Using Persistent Data and Locking.


Application security and user identification

All applications must ensure that malicious users cannot make improper use of their resources. Additionally, many applications require user identification, typically to control the portions of a site that the user can access, to control the operations that the user can perform, or to provide user-specific content.

ColdFusion provides the following two forms of application security to address these issues:

  • Resource (file and directory-based) security Limits the ColdFusion resources, such as tags, functions, and data sources that application pages in particular directories can access. You must consider the resource security needs of your application when you design the application directory structure.
  • User (programmatic) security Provides an authentication (login) mechanism and a role-based authorization mechanism to ensure that users can only access and use selected features of the application. User security also incorporates a user ID which you can use to customize page content. To implement user security, you include security code, such as the cflogin and cfloginuser tags, in your application.

For detailed information on implementing security, see Securing Applications.


Mapping an application

When you design a ColdFusion application, you must map the directory structure. This activity is an important step in designing a ColdFusion application. Before you start building the application, you must establish a root directory for the application. You can store application pages in subdirectories of the root directory.

The following sections describe how you determine where to place your application pages and the Application.cfm and OnRequestEnd pages in a directory structure. For more information on how to define and use the Application.cfm page, see Creating the Application.cfm page


Processing the Application.cfm and OnRequestEnd.cfm pages

ColdFusion uses similar, but different, rules to locate and process the Application.cfm and OnRequestEnd.cfm pages.


Processing the Application.cfm page

When ColdFusion receives a request for an application page, it searches the page's directory for a file named Application.cfm. If one exists, the Application.cfm code is logically included at the beginning of that application page.

If the application page directory does not have an Application.cfm page, ColdFusion searches up the directory tree until it finds an Application.cfm page. If several directories in the directory tree have an Application.cfm page, ColdFusion uses the first page it finds. If the Application.cfm page is present in the directory tree (and has the required permissions set), you cannot prevent ColdFusion from including it.

ColdFusion processes only one Application.cfm page for each request. If a ColdFusion page has a cfinclude tag pointing to an additional CFML page, ColdFusion does not search for an Application.cfm page when it includes the additional page.

If your application runs on a UNIX platform, which is case-sensitive, you must spell Application.cfm with an initial capital letter.


Processing the OnRequestEnd.cfm page

Just as the Application.cfm page runs before the code on an application page, an OnRequestEnd.cfm page runs, if it exists, after each application page in the same application.

The OnRequestEnd.cfm page must be in the same directory as the Application.cfm page ColdFusion uses for the current page. ColdFusion does not search beyond that directory, so it does not run an OnRequestEnd.cfm page that resides in another directory.

The OnRequestEnd.cfm page does not run if there is an error or an exception on the application page, or if the application page executes the cfabort or cfexit tag.

On UNIX systems, you must spell the OnRequestEnd.cfm file with the capital letters shown.


Defining the directory structure

Defining an application directory structure with an application-specific root directory has a the following advantages:

  • Development The application is easier to develop and maintain, because the application page files are well-organized.
  • Portability You can easily move the application to another server or another part of a server without changing any code in the application page files.
  • Application-level settings Application pages that are under the same directory can share application-level settings and functions.
  • Security Application pages that are under the same directory can share web server security settings.

When you put your application in an application-specific directory hierarchy, you can use a single Application.cfm page in the application root directory, or put different Application.cfm pages that govern individual sections of the application in different directories.

You can divide your logical web application into multiple ColdFusion applications by using multiple Application.cfm pages with different application names. Alternatively, you can use multiple Application.cfm pages that specify the same application name, but have different common code, for different subsections of your application.

The directory trees in the following figure show two approaches to implementing an application framework:

  • In the example on the left, a company named Web Wonders, Inc. uses a single Application.cfm file installed in the application root directory to process all application page requests.
  • In the example on the right, Bandwidth Associates uses the settings in individual Application.cfm files to create individual ColdFusion applications at the departmental level. Only the Products application pages are processed using the settings in the root Application.cfm file. The Consulting, Marketing, and Sales directories each have their own Application.cfm file.

This is a picture of the feature being described.


Creating the Application.cfm page

The Application.cfm page defines application-level settings and functions such as the following:

  • Application name
  • Client, Application, and Session variable management options
  • Page processing settings
  • Default variables, data sources, style settings, and other application-level constants
  • Login processing
  • Application-specific error handling


Naming the application

In ColdFusion, you define an application by giving it a name using the cfapplication tag. By using a specific application name in a cfapplication tag, you define a set of pages as part of the same logical application. Although you can create an application by putting a cfapplication tag with the application name on each page, you normally put the tag in the Application.cfm file; for example:

<cfapplication name="SearchApp">

Note: The value you set for the name attribute in the cfapplication tag is limited to 64 characters.

ColdFusion supports unnamed applications, which are useful for ColdFusion applications that must interoperate with JSP tags and servlets. Consider creating an unnamed application only if your ColdFusion pages must share Application or Session scope data with existing JSP pages and servlets. You cannot have more than one unnamed application on a server. For more information on using unnamed applications, see Integrating J2EE and Java Elements in CFML Applications.


Setting the Client, Application, and Session variables options

You use the cfapplication tag to specify client state and persistent variable use, as follows:

  • To use Client scope variables, you must specify clientManagement=True.
  • To use Session scope variables, you must specify sessionManagment=True.

You can also optionally do the following:

  • Set application-specific time-outs for Application and Session scope variables. These settings override the default values set in the ColdFusion Administrator.
  • Specify a storage method for Client scope variables. This setting overrides the method set in the ColdFusion Administrator.
  • Specify not to use cookies on the client browser.

For more information on configuring these options, see Using Persistent Data and Locking and CFML Reference.


Defining page processing settings

The cfsetting tag lets you specify the following page processing attributes that you might want to apply to all pages in your application:

Attribute | Use
showDebugOutput | Specifies whether to show debugging output. This setting cannot enable debugging if it is disabled in the ColdFusion Administrator. However, this option can ensure that debugging output is not displayed, even if the Administrator enables it.
requestTimeout | Specifies the page request time-out. If ColdFusion cannot complete processing a page within the time-out period, it generates an error. This setting overrides the setting in the ColdFusion Administrator. You can use this setting to increase the page time-out if your application or page frequently accesses external resources that might be particularly slow, such as external LDAP servers or web services providers.
enableCFOutputOnly | Disables output of text that is not included inside cfoutput tags. This setting can help ensure that extraneous text that might be in your ColdFusion pages does not get displayed.

Often, you use the cfsetting tag on individual pages, but you can also use it in your Application.cfm. For example, you might use it in multi-application environment to override the ColdFusion Administrator settings in one application.


Setting application default variables and constants

You can set default variables and application-level constants on the Application.cfm page. For example, you can specify the following values:

  • A data source
  • A domain name
  • Style settings, such as fonts or colors
  • Other important application-level variables

Often, an Application.cfm page uses one or more cfinclude tags to include libraries of commonly used code, such as user-defined functions, that are required on many of the application’s pages.


Processing logins

When an application requires a user to log in, you typically put the cflogin tag on the Application.cfm page. For detailed information on security and creating logins, including an Application.cfm page that manages user logins, see Securing Applications.


Handling errors

You can use the cferror tag on your Application.cfm page to specify application-specific error-handling pages for request, validation, or exception errors, as shown in the example in the following section. This way you can include application-specific information, such as contact information or application or version identifiers, in the error message, and you display all error messages in the application in a consistent manner.

You can also use the Application.cfm page to develop more sophisticated application-wide error-handling techniques, including error-handling methods that provide specific messages or use structured error-handling techniques.

For more information on error pages and error handling, see Handling Errors.


Example: an Application.cfm page

The following example shows a sample Application.cfm file that uses several of the techniques typically used in Application.cfm pages. For the sake of simplicity, it does not show login processing; for a login example, see Securing Applications.

<!--- Set application name and enable Client and Session variables --->
<cfapplication name="Products"
   clientmanagement="Yes"
   clientstorage="myCompany"
   sessionmanagement="Yes">

<!--- Set page processing attributes --->
<cfsetting showDebugOutput="No" >

<!--- Set custom global error handling pages for this application--->
<cferror type="request"
   template="requesterr.cfm"
   mailto="admin@company.com">
<cferror type="validation"
   template="validationerr.cfm">

<!--- Set the Application variables if they aren’t defined. --->
<!--- Initilialize local app_is_initialized flag to false --->
<cfset app_is_initialized = False>
<!--- Get a readonly lock --->
<cflock scope="application" type="readonly" timeout=10>
<!--- Read init flag and store it in local variable --->
   <cfset app_is_initialized = IsDefined("Application.initialized")>
</cflock>
<!--- Check the local flag --->
<cfif not app_is_initialized >
<!--- Application variables are Not initialized yet.
      Get an exclusive lock to write scope --->
   <cflock scope="application" type="exclusive" timeout=10>
      <!--- Check the Application scope initialized flag since another request could
         have set the variables after this page released the read-only lock. --->
      <cfif not IsDefined("Application.initialized") >
         <!--- Do initializations --->
         <cfset Application.ReadOnlyData.Company = "MyCompany" >
         <!--- and so on --->
         <!--- Set the Application scope initialization flag --->
         <cfset Application.initialized = "yes">
      </cfif>
   </cflock>
</cfif>

<!--- Set a Session variable.--->
<cflock  timeout="20" scope="Session" type="exclusive">
   <cfif not IsDefined("session.pagesHit")>
      <cfset session.pagesHit=1>
   <cfelse>
      <cfset session.pagesHit=session.pagesHit+1>
   </cfif>
</cflock>

<!--- Set Application-specific Variables scope variables. --->
<cfset mainpage = "default.cfm">
<cfset current_page = "#cgi.path_info#?#cgi.query_string#">

<!--- Include a file containing user-defined functions called throughout
      the application --->
<cfinclude template="commonfiles/productudfs.cfm">


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfapplication name="Products"
   clientmanagement="Yes"
   clientstorage="myCompany"
   sessionmanagement="Yes">
Names the application, enables Client and Session scope variables, and sets the client variable store to the myCompany data source.
<cfsetting showDebugOutput="No" >
Ensure that debugging output is not displayed, if the ColdFusion Administrator enables it.
<cferror type="request"
   template="requesterr.cfm"
   mailto="admin@company.com">
<cferror type="validation"
   template="validationerr.cfm">
Specifies custom error handlers for request and validation errors encountered in the application. Specifies the mailing address for use in the request error handler.
<cfset app_is_initialized = False>
.
.
.
Sets the Application scope variables, if they are not already set. For a detailed description of the technique used to set the Application scope variables, see Using Persistent Data and Locking.
<cflock  timeout="20"
      scope="Session"
      type="exclusive">
   <cfif not IsDefined("session.pagesHit")>
      <cfset session.pagesHit=1>
   <cfelse>
      <cfset session.pagesHit=
         session.pagesHit+1>
   </cfif>
</cflock>
Sets the Session scope pagesHit variable, which counts the number of pages touched in this session. If the variable does not exist, creates it. Otherwise, increments it.
<cfset mainpage = "default.cfm">
<cfset current_page =
   "#cgi.path_info#?#cgi.query_string#">
Sets two Variables scope variables that are used throughout the application. Creates the current_page variable dynamically; it’s value varies from request to request.
<cfinclude template=
   "commonfiles/productudfs.cfm">
Includes a library of user-defined functions that are used in most pages in the application.


Optimizing ColdFusion applications

You can optimize your ColdFusion application in many ways. Much of optimizing ColdFusion involves good development and coding practices. For example, good database design and usage is a prime contributor to efficient ColdFusion applications.

In several places, this book documents optimization techniques as part of the discussion of the related ColdFusion topic. This section provides information about general ColdFusion optimization tools and strategies, and particularly about using CFML caching tags for optimization. This section also contains information on optimizing database use, an important area for application optimization.

The ColdFusion Administrator provides caching options for ColdFusion pages and SQL queries. For information on these options see the Administrator online Help and Administering ColdFusion MX.

For information on debugging techniques that can help you identify slow pages, see Debugging and Troubleshooting Applications.

For additional information on optimizing ColdFusion, see the Macromedia ColdFusion support center at http://www.macromedia.com/support/coldfusion.


Caching ColdFusion pages that change infrequently

Some ColdFusion pages produce output that changes infrequently. For example, you might have an application that extracts a vendor list from a database or produces a quarterly results summary. Normally, when ColdFusion gets a request for a page in the application, it does all the business logic and display processing required to produce the report or generate and display the list. If the results change infrequently, this can be an inefficient use of processor resources and bandwidth.

The cfcache tag tells ColdFusion to cache the HTML that results from processing a page request in a temporary file on the server. This HTML does not need to be generated each time the page is requested. When ColdFusion gets a request for a cached CFML page, it retrieves the pregenerated HTML page without having to process the CFML page. ColdFusion can also cache the page on the client. If the client browser has its own cached copy of the page from a previous viewing, ColdFusion instructs the browser to use the client’s page rather than resending the page.

Note: The cfcache tag caching mechanism considers each URL to be a separate page. Therefore, http://www.mySite.com/view.cfm?id=1 and http://www.mySite.com/view.cfm?id=2 result in two separate cached pages. Because ColdFusion caches a separate page for each unique set of URL parameters, the caching mechanism accommodates pages for which different parameters result in different output.


Using the cfcache tag

You tell ColdFusion to cache the page results by putting a cfcache tag on your ColdFusion page above code that outputs text. The tag lets you specify the following information:

  • Whether to cache the page results on the server, the client system, or both. The default is both. The default is optimal for pages that are identical for all users. If the pages contain client-specific information, or are secured with ColdFusion user security, set the action attribute in the cfcache tag to ClientCache.
  • The directory on the server in which to store the cached pages. The default directory is cf_root/cache. It is a good practice to create a separate cache directory for each application. Doing so can prevent the cfcache tag flush action from inappropriately flushing more than one application’s caches at a time.
  • The time span indicating how long the page lasts in the cache from when it is stored until it is automatically flushed.

You can also specify several attributes for accessing a cached page on the web server, including a user name and password (if required by the web server), the port, and the protocol (HTTP or HTTPS) to use to access the page.

Place the cfcache tag above any code on your page that generates output, typically at the top of the page body. For example, the following tag tells ColdFusion to cache the page on both the client and the server. On the server, the page is cached in the e:/temp/page_cache directory. ColdFusion retains the cached page for one day.

<cfcache timespan="#CreateTimespan(1, 0, 0, 0)#" directory="e:/temp/page_cache">

Caution:If your Application.cfm page displays text; for example, if it includes a header page, use the cfcache tag on the Application.cfm page in addition to the pages that you cache. Otherwise, ColdFusion displays the Application.cfm page output twice on each cached page.


Flushing cached pages

ColdFusion automatically flushes any cached page if you change the code on the page. It also automatically flushes pages after the expiration timespan passes.

You can use the cfcache tag with the action="flush" attribute to immediately flush one or more cached pages. You can optionally specify the directory that contains the cached pages to be flushed and a URL pattern that identifies the pages to flush. If you do not specify a URL pattern, all pages in the directory are flushed. The URL pattern can include asterisk (*) wild cards to specify parts of the URL that can vary.

When you use the cfcache tag to flush cached pages, ColdFusion deletes the pages cached on the server. If a flushed page is cached on the client system, it is deleted, and a new copy gets cached, the next time the client tries to access the CFML page.

The following example flushes all the pages in the e:/temp/page_cache/monthly directory that start with HR:

<cfcache action="flush" directory="e:/temp/page_cache/monthly" expirURL="HR*">

If you have a ColdFusion page that updates data you use in cached pages, the page that does the updating includes a cfcache tag that flushes all pages that use the data.

For more information on the cfcache tag, see CFML Reference.


Caching parts of ColdFusion pages

In some cases, your ColdFusion page might contain a combination of dynamic information that ColdFusion must generate each time it displays the page, and parts it generates dynamically, but that change less frequently. In this case, you cannot use the cfcache tag to cache the entire page. Instead, use the cfsavecontent tag to cache the infrequently-changed content.

The cfsavecontent tag saves the results of processing the tag body in a variable. For example, if the body of the cfsavecontent tag contains a cfexecute tag that runs an executable program that displays data, the variable saves the output.

You can use the cfsavecontent tag to cache infrequently changing output in a shared scope variable. If the information is used throughout the application, save the output in the Application scope. If the information is client-specific, use the Session scope. Because of the overhead of locking shared scope variables, use this technique only if the processing overhead of generating the output is substantial.

Before you use this technique, also consider whether other techniques are more appropriate. For example, query caching eliminates the need to repeat a common query. However, if the effort of processing the data or in formatting the output is substantial, using the cfsavecontent tag can save processing time.

Using this technique, if the variable exists, the page uses the cached output. If the variable does not exist, the page gets the data, generates the output, and saves the results to the shared scope variable.

The following example shows this technique. It has two parts. The first part welcomes the user and prints out a random lucky number. This part runs and produces a different number each time a user opens the page. The second part performs a database query to get information that changes infrequently, in this case a listing of the current special sale items. It uses the cfsavecontent tag to get the data only when needed.

Tip: If you use this technique frequently, consider incorporating it in a custom CFML tag.

<!--- Greet the user --->
<cfoutput>
   Welcome to our home page.<br>
   The time is #TimeFormat(Now())#.<br>
   Your lucky number is: #RandRange(1,1000)#<br>
   <hr><br>
</cfoutput>

<!--- Set a flag to indicate whether the Application scope variable exists --->
<cflock scope="application" timeout="20" type="readonly">
   <cfset IsCached = Not IsDefined("Application.ProductCache")>
</cflock>

<!--- If the flag is false, query the DB, and save an image of
   the results output to a variable --->
<cfif not IsCached>
   <cfsavecontent variable="ProductCache">
   <!--- Perform database query --->
      <cfquery dataSource="ProductInfo" name="specialQuery">
         SELECT ItemName, Item_link, Description, BasePrice
         FROM SaleProducts
      </cfquery>
<!--- Calculate sale price and display the results --->
      <h2>Check out the following specials</h2>
      <table>
      <cfoutput query="specialQuery">
         <cfset salePrice= BasePrice * .8>
         <tr>
            <td>#ItemNAme#</td>
            <td>#Item_Link#</td>
            <td>#Description#</td>
            <td>#salePrice#</td>
         </tr>
      </cfoutput>
      </table>
   </cfsavecontent>

<!--- Save the results in the Applicaiton scope --->
   <cflock scope="Application" type="Exclusive" timeout=30>
      <cfset Application.productCache = ProductCache>
   </cflock>
</cfif>

<!--- Use the Application scope variable to display the sale items --->
<cflock scope="application" timeout="20" type="readonly">
   <cfoutput>#Application.ProductCache#</cfoutput>
</cflock>


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfoutput>
   Welcome to our home page.<br>
   The time is #TimeFormat(Now())#.<br>
   Your lucky number is:
      #RandRange(1,1000)#<br>
   <hr><br>
</cfoutput>
Displays the part of the page that must change each time.
<cflock scope="application" timeout="20"
      type="readonly">
   <cfset IsCached = IsDefined
      ("Application.ProductCache")>
</cflock>
Inside a read-only lock, tests to see if the part of the page that changes infrequently is already cached in the Application scope, and sets a boolean flag variable with the result.
<cfif not IsCached>
   <cfsavecontent variable="ProductCache">
If the flag is False, uses a cfsavecontent tag to save output in a Variables scope variable. Using the Variables scope eliminates the need to do a query (which can take a long time) in an Application scope lock.
<cfquery dataSource="ProductInfo"
      name="specialQuery">
   SELECT ItemName, Item_link,
      Description, BasePrice
   FROM SaleProducts
</cfquery>
Queries the database to get the necessary information
<h2>Check out the following specials</h2>
<table>
   <cfoutput query="specialQuery">
      <cfset salePrice = BasePrice * .8>
      <tr>
         <td>#ItemNAme#</td>
         <td>#Item_Link#</td>
         <td>#Description#</td>
         <td>#salePrice#</td>
      </tr>
   </cfoutput>
   </table>
Displays the sale items in a table. Inside a cfoutput tag, calculates each item’s sale price and displays the item information in a table row.
Because this code is inside a cfsavecontent tag, ColdFusion does not display the results of the cfoutput tag. Instead, it saves the formatted output as HTML and text in the ProductCache variable.
</cfsavecontent>
Ends the cfsavecontent tag block.
<cflock scope="Application"
type="Exclusive"
      timeout=30>
   <cfset Application.productCache =
      productcache>
</cflock>
Inside an Exclusive cflock tag, saves the contents of the local variable ProdcutCache in the Application scope variable Application.productCache.
</cfif>
Ends the code that executes only if the Application.productCache variable does not exist.
<cflock scope="application" timeout="20"
      type="readonly">
   <cfoutput>#Application.ProductCache#</
cfoutput>
</cflock>
Inside a cflock tag, displays the contents of the Application.productCache variable.


Optimizing database use

Two important ColdFusion tools for optimizing your use of databases are the cfstoredproc tag and the cfquery tag cachedWithin attribute.

Note: Poor database design and incorrect or inefficient use of the database are among the most common causes of inefficient applications. Consider the different methods that are available for using databases and information from databases when you design your application. For example, if you need to average the price of a number of products from an SQL query, it is more efficient to use SQL to get the average than to use a loop in ColdFusion.


Using stored procedures

The cfstoredproc tag lets ColdFusion use stored procedures in you database management system. A stored procedure is a sequence of SQL statements that is assigned a name, compiled, and stored in the database system. Stored procedures can encapsulate programming logic in SQL statements, and database systems are optimized to execute stored procedures efficiently. As a result, stored procedures are faster than cfquery tags.

You use the cfprocparam tag to send parameters to the stored procedure, and the cfproresult tag to get the record sets that the stored procedure returns.

The following example executes a Sybase stored procedure that returns three result sets, two of which the example uses. The stored procedure returns the status code and one output parameter, which the example displays.

<!--- cfstoredproc tag --->
<cfstoredproc procedure = "foo_proc" dataSource = "MY_SYBASE_TEST"
   username = "sa" password = "" returnCode = "Yes">

   <!--- cfprocresult tags --->
   <cfprocresult name = RS1>
   <cfprocresult name = RS3 resultSet = 3>

   <!--- cfprocparam tags --->
   <cfprocparam type = "IN"
      CFSQLType = CF_SQL_INTEGER
         value = "1"    dbVarName = @param1>
   <cfprocparam type = "OUT"   CFSQLType = CF_SQL_DATE
      variable = FOO dbVarName = @param2>
<!--- Close the cfstoredproc tag --->
</cfstoredproc>

<cfoutput>
   The output param value: ’#foo#’<br>
</cfoutput>

<h3>The Results Information</h3>
<cfoutput query = RS1>
   #name#,#DATE_COL#<br>
</cfoutput>
<br>
<cfoutput>
   <hr>
   Record Count: #RS1.recordCount#<br>
   Columns: #RS1.columnList#<br>
   <hr>
</cfoutput>

<cfoutput query = RS3>
   #col1#,#col2#,#col3#<br>
</cfoutput>
<br>
<cfoutput>
   <hr><br>
   Record Count: #RS3.recordCount#<br>
   Columns: #RS3.columnList#<br>
   <hr>

   The return code for the stored procedure is: ’#cfstoredproc.statusCode#’<br>
</cfoutput>


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfstoredproc procedure = "foo_proc"
   dataSource = "MY_SYBASE_TEST" username = "sa"
   password = "" returnCode = "Yes">
Runs the stored procedure foo_proc on the MY_SYBASE_TEST data source. Populates the cfstoredproc. statusCode variable with the status code returned by stored procedure.
<cfprocresult name = RS1>
<cfprocresult name = RS3 resultSet = 3>
Gets two record sets from the stored procedure: the first and third result sets it returns.
<cfprocparam type = "IN"
   CFSQLType = CF_SQL_INTEGER
      value = "1" dbVarName = @param1>
<cfprocparam type = "OUT" CFSQLType = CF_SQL_DATE
   variable = FOO dbVarName = @param2>
</cfstoredproc>
Specifies two parameters for the stored procedure, an input parameter and an output parameter. Sets the input parameter to 1 and the ColdFusion variable that gets the output to FOO.
Ends the cfstoredproc tag body.
<cfoutput>
   The output param value: ’#foo#’<br>
</cfoutput>

<h3>The Results Information</h3>
<cfoutput query = RS1>
   #name#,#DATE_COL#<br>
</cfoutput>
<br>

<cfoutput>
   <hr>
   Record Count: #RS1.recordCount#<br>
   Columns: #RS1.columnList#<br>
   <hr>
</cfoutput>

<cfoutput query = RS3>
   #col1#,#col2#,#col3#<br>
</cfoutput>
<br>

<cfoutput>
   <hr><br>
   Record Count: #RS3.recordCount#<br>
   Columns: #RS3.columnList#<br>
   <hr>
   The return code for the stored procedure is:
   ’#cfstoredproc.statusCode#’<br>
</cfoutput>
Displays the results of running the stored procedure:
  • The output parameter value,
  • The contents of the two columns in the first record set identified by the name and DATE_COL variables. Note that you set the values of these variables elsewhere on the page.
  • The number of rows and the names of the columns in the first record set
  • The contents of the columns in the other record set identified by the col1, col2, and col3 variables.
  • The number of rows and the names of the columns in the record set
  • The status value returned by the stored procedure.

For more information on creating stored procedures, see your database management software documentation. For more information on using the cfstoredproc tag, see the CFML Reference.


Using the cfquery tag cachedWithin attribute

The cfquery tag cachedWithin attribute tells ColdFusion to save the results of a database query for a specific period of time. This way, ColdFusion accesses the database on the first page request, and does not query the database on further requests until the specified time expires. Using the cachedWithin attribute can significantly limit the overhead of accessing databases that do not change rapidly.

This technique is useful if the database contents only change at specific, known, times. or if the database does not change frequently and the purpose of the query does not require absolutely up to date results

You must use the CreateTimeSpan function to specify the cachedWithin attribute value (in days, hours, minutes, seconds format). For example, the following code caches the results of getting the contents of the Employees table of the CompanyInfo data source for one hour.

<cfquery datasource="CompanyInfo" name="master"

   cachedWithin=#CreateTimeSpan(0,1,0,0)#>
   SELECT * FROM Employees
</cfquery>


Providing visual feedback to the user

If an application might take a while to process data, it is useful to provide visual feedback to indicate that something is happening so the user does not assume that there is a problem and request the page again. Although doing this does not optimize your application’s processing efficiency, it does make the application appear more responsive.

You can use the cfflush tag to return partial data to a user, as shown in Retrieving and Formatting Data.

You can also use the cfflush tag to create a progress bar. For information on this technique, see the technical article "Understanding Progress Meters in ColdFusion 5" at http://www.macromedia.com/v1/handlers/index.cfm?id=21216&method=full. (Although this article was written for ColdFusion 5, it also applies to ColdFusion MX.)

Previous


Handling Errors

ColdFusion includes many tools and techniques for responding to errors that your application encounters. These tools include error handling mechanisms and error logging tools. This chapter describes these tools and how to use them.

This chapter does not discuss techniques for preventing errors, including methods for specifying user input validation. It also does not discuss code debugging. For information on user input validation, see Retrieving and Formatting Data and Building Dynamic Forms. For information on debugging see Debugging and Troubleshooting Applications.

Contents
  • About Error Handling in ColdFusion
  • Understanding Errors
  • Error Messages and the Standard Error Format
  • Determining Error-Handling Strategies
  • Specifying Custom Error Messages with cferror
  • Logging Errors with the cflog tag
  • Handling Run-time Exceptions with ColdFusion Tags
Next


About Error Handling in ColdFusion

By default, ColdFusion generates its own error messages when it encounters errors. In addition, it provides a variety of tools and techniques for you to customize error information and handle errors when they occur. You can use any of the following error-management techniques:

  • Specify custom pages for ColdFusion to display in each of the following cases:
    • when a CFML page is missing (the Missing Template Handler page)
    • when an otherwise-unhandled exception error occurs during the processing of a page (the Site-wide Error Handler page)

      • You specify these pages on the ColdFusion Administrator Server Settings page. For more information on specifying custom error pages in the Administrator, see the Administrator Help.

  • Use the cferror tag to specify ColdFusion pages to handle specific types of errors.
  • Log errors. ColdFusion logs certain errors by default. You can use the cflog tag to log other errors.
  • Use the cftry, cfcatch, cfthrow, and cfrethrow tags to catch and handle exception errors directly on the page where they occur.
  • In CFScript, use the try and catch statements to handle exceptions.

The remaining sections in this chapter provide the following information:

  • The basic building blocks for understating types of ColdFusion errors and how ColdFusion handles them
  • How to use the cferror tag to specify error-handling pages
  • How to log errors
  • How to handle ColdFusion exceptions

Note: This chapter discusses using the cftry and cfcatch tags, but not the equivalent CFScript try and catch statements. The general discussion of exception handling in this chapter applies to tags and CFScript statements. However, the code that you use and the information available in CFScript differs from those in the tags. See Handling errors in UDFs for more information on handling exceptions in CFScript.


Understanding Errors

There are many ways to look at errors. For example you can look at errors by their causes. You can also look at them by their effects, particularly by whether your application can recover from them. You can also look at them the way ColdFusion does. The following sections discuss these ways of looking at errors.


About error causes and recovery

Errors can have many causes. Depending on the cause, the error might be recoverable. A recoverable error is one for which your application can identify the error cause and take action on the problem. Some errors, such as time-out errors, might be recoverable without indicating to the user that an error was encountered. An error for which a requested application page does not exist is not recoverable, and the application can only display an error message.

Errors such as validation errors, for which the application cannot continue processing the request, but can provide an error-specific response, can also be considered recoverable. For example, an error that occurs when a user enters text where a number is required can be considered recoverable, because the application can recognize the error and redisplay the data field with a message providing information about the error’s cause and telling the user to reenter the data.

Some types of errors might be recoverable in some, but not all circumstances. For example, your application can retry a request following a time-out error, but it must also be prepared for the case where the request always times out.

Error causes fall in the broad categories listed in the following table:

Category | Description
Program errors | Can be in the code syntax or the program logic. The ColdFusion compiler identifies and reports program syntax errors when it compiles CFML into Java classes. Errors in your application logic are harder to locate. For information on debugging tools and techniques, see Debugging and Troubleshooting Applications. Unlike ColdFusion syntax errors, SQL syntax errors are only caught at run time.
Data errors | Are typically user data input errors. You use validation techniques to identify errors in user input data and enable the user to correct the errors.
System errors | Can come from a variety of causes, including database system problems, time-outs due to excessive demands on your server, out-of-memory errors in the system, file errors, and disk errors.

Although these categories do not map completely to the way ColdFusion categorizes errors they provide a useful way of thinking about errors and can help you in preventing and handling errors in your code.


ColdFusion error types

Before you can effectively manage ColdFusion errors, you must understand how ColdFusion classifies and handles them. ColdFusion categorizes errors as detailed in the following table:

Type
Description
Exception
An error that prevents normal processing from continuing. All ColdFusion exceptions are, at their root, Java exceptions.
Missing template
An HTTP request for a CFML page that cannot be found. Generated if a browser requests a CFML page that does not exist.
Missing template errors are different from missing include exceptions, which result from cfinclude tags or custom tag calls that cannot find their targets.
Form field data validation
User data that does not meet the server-side form field validation rules in a form being submitted. You specify server-side form validation by using hidden HTML form fields. All other types of server-side validation, such as the cfparam tag generate run-time exceptions. For more information on validating form fields see Building Dynamic Forms.

Most ColdFusion errors are exceptions. The following sections describe them in detail.


About ColdFusion exceptions

You can categorize ColdFusion exceptions in two ways:

  • When they occur
  • Their Type


When exceptions occur

ColdFusion errors can occur at two times, when the CFML is compiled into Java and when the resulting Java executes, called run-time exceptions.


Compiler exceptions

Compiler exceptions are programming errors that ColdFusion identifies when it compiles CFML into Java. Because compiler exceptions occur before the ColdFusion page is converted to executable code, you cannot handle them on the page that causes them. However, other pages can handle these errors. For more information, see Handling compiler exceptions


Run-time exception

A run-time exception occurs when the compiled ColdFusion Java code runs. It is an event that disrupts the application’s normal flow of instructions. Exceptions can result from system errors or program logic errors. Run-time exceptions include:

  • Error responses from external services, such as an ODBC driver or CORBA server
  • CFML errors or the results of cfthrow or cfabort tags
  • Internal errors in the ColdFusion Server


ColdFusion exception types

ColdFusion exceptions have types that you specify in the cferror, cfcatch, and cfthrow error-handling tags. A cferror or cfcatch tag will handle only exceptions of the specified type. You identify an exception type by using an identifier from one (or more) of the following type categories:

  • Basic
  • Custom
  • Advanced
  • Java class

Note: Use only custom error type names and the Application basic type name in cfthrow tags. All other built-in exception type names identify specific types of system-identified errors, so you should not use them for errors that you identify yourself.


Basic exception types

All ColdFusion exceptions except for custom exceptions belong to a basic type category. These types consist of a broadly-defined categorization of ColdFusion exceptions. The following table describes the basic exception types:

Type
Type name
Description
Database failures
Database
Failed database operations, such as failed SQL statements, ODBC problems, and so on.
Missing include file errors
MissingInclude
Errors where files specified by the cfinclude, cfmodule, and cferror tags are missing. (A cferror tag generates a missingInclude error only when an error of the type specified in the tag occurs.)
The MissingInclude error type is a subcategory of Template error. If you do not specifically handle the MissingInclude error type, but do handle the Template error type, the Template error handler catches these errors. MissingInclude errors are caught at run time.
Template errors
Template
General application page errors, including invalid tag and attribute names. Most Template errors are caught at compile time, not run time.
Object exceptions
Object
Exceptions in ColdFusion code that works with objects.
Security exceptions
Security
Catchable exceptions in ColdFusion code that works with security.
Expression exceptions
Expression
Failed expression evaluations; for example, if you try to add 1 and "a".
Locking exceptions
Lock
Failed locking operations, such as when a cflock critical section times out or fails at run time.
Verity Search engine exception
SearchEngine
Exceptions generated by the Verity search engine when processing cfindex, cfcolletion, or cfsearch tags.
Application-defined exception events raised by cfthrow
Application
Custom exceptions generated by a cfthrow tag that do not specify a type, or specify the type as Application.
All exceptions
Any
Any exceptions. Includes all types in this table and any exceptions that are not specifically handled in another error handler, including unexpected internal and external errors.

Note: The Any type includes all error with the Java object type of java.lang.Exception. It does not include java.lang.Throwable errors. To catch Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute.


Custom exceptions

You can generate an exception with your own type by specifying a custom exception type name, for example MyCustomErrorType, in a cfthrow tag. You then specify the custom type name in a cfcatch or cferror tag to handle the exception. Custom type names must be different from any built-in type names, including basic types and Java exception classes.


Advanced exception types

The Advanced exceptions consist of a set of specific, narrow exception types. These types are supported in ColdFusion MX for backward-compatibility. For a list of advanced exception types, see the CFML Reference.


Java exception classes

Every ColdFusion exception belongs to, and can be identified by, a specific Java exception class in addition to its basic, custom, or advanced type. The first line of the stack trace in the standard error output for an exception identifies the exception’s Java class.

For example, if you attempt to use an array function such as ArrayIsEmpty on an integer variable, ColdFusion generates an exception that belongs to the Expression exception basic type and the coldfusion.runtime.NonArrayException Java class.

In general, most applications do not need to use Java exception classes to identify exceptions. However, you can use Java class names to catch exceptions in non-CFML Java objects; for example, the following line catches all Java input/output exceptions:

<cfcatch type="java.io.IOException">


How ColdFusion handles errors

The following sections describes briefly how ColdFusion handles errors. The rest of this chapter expands on this information.


Missing template errors

If a user requests a page that the ColdFusion cannot find, and the Administrator Server Settings Missing Template Handler field specifies a Missing Template Handler page, ColdFusion uses that page to display error information. Otherwise, it displays a standard error message.


Form field validation errors

When a user enters invalid data in an HTML tag that uses server-side (hidden form field) data validation, and a cferror tag in the Application.cfm page specifies a Validation error handler, ColdFusion displays the specified error page. Otherwise, it displays the error information in a standard format that consists of a default header, a bulleted list describing the error(s), and a default footer. For more information on using hidden form field validation, see Validating form field data types.


Compiler exception errors

If ColdFusion encounters a compiler exception, how it handles the exception depends on whether the error occurs on a requested page or on an included page:

  • If the error occurs on a page that is accessed by a cfinclude or cfmodule tag, or on a custom tag page that you access using the cf_ notation, ColdFusion handles it as a run-time exception in the page that accesses the tag. See the Run-time exception errors section, next, for a description of how these errors are handled.
  • If the error occurs directly on the requested page, ColdFusion handles the error as follows:
    • If a cferror tag on the Application.cfm page specifies an error handler for the exception type, ColdFusion displays the specified error page.
    • If the Administrator Settings Site-wide Error Handler field specifies an error handler page, ColdFusion displays the specified error page.
    • Otherwise, ColdFusion reports the error using the standard error message format described in Error Messages and the Standard Error Format.


Run-time exception errors

If ColdFusion encounters a run-time exception, it does the action for the first matching condition in the following table:

Condition | Action
The code with the error is inside a cftry tag and the exception type is specified in a cfcatch tag. | Executes the code in the cfcatch tag. If the cftry block does not have a cfcatch tag for this error, tests for an appropriate cferror handler or site-wide error handler.
A cferror tag specifies an exception error handler for the exception type. | Uses the error page specified by the cferror tag.
The Administrator Settings Site-wide Error Handler field specifies an error handler page. | Uses the custom error page specified by the Administrator setting.
A cferror tag specifies a Request error handler. | Uses the error page specified by the cferror tag.
The default case. | Uses the standard error message format

For example, if an exception occurs in CFML code that is not in a cftry block, but a cferror tag specifies a page to handle this error type, ColdFusion uses the specified error page.


Error Messages and the Standard Error Format

If your application does not handle an error, ColdFusion displays a diagnostic message in the user’s browser, such as the one shown in the following figure:

This is a picture of the feature being described.

Error information is also written to a log file for later review. (For information on error logging, see Logging Errors with the cflog tag.)

The standard error format consists of the information listed in the following table. ColdFusion does not always display all sections.

Section
Description
Error description
A brief, typically on-line, description of the error.
Error message
A detailed description of the error. The error message diagnostic information displayed depends on the type of error. For example, if you specify an invalid attribute for a tag, this section includes a list of all valid tag attributes.
Error location
The page and line number where ColdFusion encountered the error, followed by a short section of your CFML that includes the line. This section does not display for all errors.
In some cases, the cause of an error can be several lines above the place where ColdFusion determines that there is a problem, so the line that initially causes the error may not be in the display/
Resources
Links to documentation, the Knowledge Base, and other resources that can help you resolve the problem.
Error environment information
Information about the request that caused the error. All error messages include the following:
  • User browser
  • User IP address
  • Date and time of error
Stack trace
The Java stack at the time of the exception, including the specific Java class of the exception. This section can be helpful if you must contact Macromedia Technical Support.
The stack trace is collapsed by default. Click the heading to display the trace.

Tip: If you get a message that does not explicitly identify the cause of the error, check the key system parameters, such as available memory and disk space.


Determining Error-Handling Strategies

As described in the section How ColdFusion handles errors, ColdFusion provides you with many options for handling errors, particularly exceptions. This section describes considerations for determining which forms of error handling to use.


Handling missing template errors

Missing template errors occur when ColdFusion receives an HTTP request for a page ending in .cfm that it cannot find. You can create your own missing template error page to present application-specific information or provide an application-specific appearance. You specify the missing template error page on the Administrator Settings page.

The missing error page can use CFML tags and variables. In particular, you can use the CGI.script_name variable in text such as the following to identify the requested page:

<cfoutput>The page #Replace(CGI.script_name, "/", "")# is not available.<br>
Make sure that you entered the page correctly.<br>
</cfoutput>

(In this code, the Replace function removes the leading slash sign from the script name to make the display more friendly.)


Handling form field validation errors

When you use server-side form field validation, the default validation error message describes the error cause plainly and clearly. However, you might want to give the error message a custom look or provide additional information such as service contact phone numbers and addresses. In this case, use the cferror tag with the Validation attribute on the Application.cfm page to specify your own validation error handler. The section Example of a validation error page provides an example of such a page.


Handling compiler exceptions

You cannot handle compiler exceptions directly on the page where they occur, because the exception is caught before ColdFusion starts running the page code. You should fix all compiler exceptions as part of the development process. Use the reported error message and the code debugging techniques discussed in Debugging and Troubleshooting Applications to identify and correct the cause of the error.

Compiler exceptions that occur on pages you access by using the cfinclude or cfmodule tags can actually be handled as run-time errors by surrounding the cfinclude or cfmodule tag in a cftry block. The compiler exception on the accessed page gets caught as a run-time error on the base page. However, you should avoid this "solution" to the problem, as the correct method for handling compiler errors is to remove them before you deploy the application.


Handling run-time exceptions

You have many choices for handling exceptions, and the exact path you take depends on your application and its needs. The following table provides a guide to selecting an appropriate technique:

Technique
Use
cftry
Place cftry blocks around specific code sections where exceptions can be expected and you want to handle those exceptions in a context-specific manner; for example, if you want to display an error message that is specific to that code.
Use cftry blocks where you can recover from an exception. For example, you can retry an operation that times out, or access an alternate resource. You can also use the cftry tag to continue processing where a specific exception will not harm your application; for example, if a missing resource is not required.
For more information, see Handling Run-time Exceptions with ColdFusion Tags.
cferror with exception- specific error handler pages
Use the cferror tag to specify error pages for specific exception types. These pages cannot recover from errors, but they can provide the user with information about the error’s cause and steps that they can take to prevent the problem.
For more information, see Specifying Custom Error Messages with cferror.
cferror with a Request error page
Use the cferror tag to specify a Request error handler that provides a customized, application-specific message for unrecoverable exceptions. Put the tag in the Application.cfm page to make it apply to all pages in an application.
A Request error page cannot use CFML tags, but it can display error variables. As a result, you can use it to display common error information, but you cannot provide error-specific instructions. Typically, Request pages display error variable values and application-specific information, including support contact information.
For example code, see Example of a request error page.
Site-wide error handler page
Specify a site-wide error handler in the Administrator to provide consistent appearance and contents for all otherwise-unhandled exceptions in all applications on your server.
Like the Request page, the Site-wide error handler cannot perform error recovery. However, it can include CFML tags in addition to the error variables.
Because a site-wide error handler prevents ColdFusion from displaying the default error message, it allows you to limit the information reported to users. It also lets you provide all users with default contact information or other instructions.


Specifying Custom Error Messages with cferror

Custom error pages allow you to control the error information that users see. You can specify custom error pages for different types of errors and handle different types of errors in different ways. For example, you can create specific pages to handle errors that could be recoverable, such as request time-outs. You can also make your error messages consistent with the look and feel of your application.

You can specify the following types of custom error message pages:

Type
Description
Validation
Handles server-side form field data validation errors. The validation error page cannot include CFML tags, but it can display error page variables.
You can use this attribute only on the Application.cfm page. It has no effect when used on any other page. Therefore, you can specify only one validation error page per application, and that page applies to all server-side validation errors.
Exception
Handles specific exception errors. You can specify individual error pages for different types of exceptions.
Request
Handles any exception that is not otherwise-handled. The request error page runs after the CFML language processor finishes. As a result, the request error page cannot include CFML tags, but can display error page variables. A request error page is useful as a backup if errors occur in other error handlers.


Specifying a custom error page

You specify the custom error pages with the cferror tag. For Validation errors, the tag must be on the Application.cfm page. For Exception and Request errors, you can set the custom error pages on each application page. However, because custom error pages generally apply to an entire application, it is more efficient to put these cferror tags in the Application.cfm file also. For more information on using the Application.cfm page, see Designing and Optimizing a ColdFusion Application.

The cferror tag has the attributes listed in the following table:

Attribute | Description
Type | The type of error that will cause ColdFusion to display this page: Exception, Request, or Validation.
Exception | Use only for the Exception type. The specific exception or exception category that will cause the page to be displayed. This attribute can specify any of the types described in About ColdFusion exceptions.
Template | The CFML page to display.
MailTo | (Optional) An e-mail address. The cferror tag sets the error page error.mailTo variable to this value. The error page can use the error.mailTo value in a message that tells the user to send an error notification. ColdFusion does not send any message itself.

The following cferror tag specifies a custom error page for exceptions that occur in locking code and informs the error page of the of an e-mail address it can use to send a notification each time this type of error occurs:

<cferror type = "exception"
exception = "lock"
template = "../common/lockexcept.cfm"
mailto = "serverr@mycompany.com">

For detailed information on the cferror tag, see the CFML Reference.


Creating an error application page

The following table lists the rules and considerations that apply to error application pages:

Type
Considerations
Validation
  • Cannot use CFML tags.
  • Can use HTML tags.
  • Can use the Error.InvalidFields, Error. validationHeader, and Error.validationFooter variables by enclosing them with pound sings (#).
  • Cannot use any other CFML variables.
Request
  • Cannot use CFML tags.
  • Can use HTML tags.
  • Can use nine CFML error variables, such as Error.Diagnostics, by enclosing them with pound sings.
  • Cannot use other CFML variables.
Exception
  • Can use full CFML syntax, including tags, functions, and variables.
  • Can use nine standard CFML Error variables and cfcatch variables. Use either Error or cferror as the prefix for both types of variables.
  • Can use other application-defined CFML variables.
  • To display any CFML variable, use the cfoutput tag.

The following table describes the variables available on error pages:

Error page type
Error variable
Description
Validation

error.invalidFields

Unordered list of validation errors that occurred. This includes any text that you specify in the value attribute or a hidden tag used to validate form input.

error.validationHeader

Text for the header of the default validation message.

error.validationFooter

Text for the footer of the default validation message.

Exception and

Request

error.browser

Browser that was running when the error occurred.

error.dateTime

Date and time when the error occurred.

error.diagnostics

Detailed error diagnostics.

error.generatedContent

Any content that ColdFusion generated in response to the request prior to the error.

error.HTTPReferer

Page containing the HTML link to the page on which the error occurred. This value is an empty string if the user specified the page directly in the browser.

error.mailTo

E-mail address of the administrator who should be notified. This value is set in the mailTo attribute of the cferror tag.

error.queryString

URL query string of the client's request, if any.

error.remoteAddress

IP address of the remote client.

error.template

Page being executed when the error occurred.

Exception only

error.messge

Error message associated with the exception.

error.rootCause

Java servelet exception reported by the JVM as the cause of the "root cause" of the exception. This variable is a Java object.

error.tagContext

Array of structures structure containing information for each tag in the tag stack The tag stack consists of each tag that is currently open. For more information, see Exception information in cfcatch blocks

error.type

Exception type. For more information, see About ColdFusion exceptions.

Exception error pages can also use all of the exception variables listed in the section Exception information in cfcatch blocks. To use these variables, replace the cfcatch prefix with cferror or error. For example, to use the exception message in an error page, refer to it as error.message.

In general, production Exception and Request pages should not display detailed error information, such as that supplied by the error.diagnostics variable. Typically, Exception pages e-mail detailed error information to an administrative address or log the information using the cflog tag instead of displaying it to the user. For more information on using the cflog tag, see Logging Errors with the cflog tag.


Example of a request error page

The following example shows a custom error page for a request error:

<html>
<head>
<title>Products - Error</title>
</head>
<body>

<h2>Sorry</h2>

<p>An error occurred when you requested this page.</p>
<p>Please send e-mail with the following information to #error.mailTo# to report
this error.</p>

<table border=1>
<tr><td><b>Error Information</b> <br>
   Date and time: #error.DateTime# <br>
   Page: #error.template# <br>
   Remote Address: #error.remoteAddress# <br>
   HTTP Referer: #error.HTTPReferer#<br>
</td></tr></table>

<p>We apologize for the inconvenience and will work to correct the problem.</p>
</body>
</html>


Example of a validation error page

The following example shows a simple custom error page for a validation error:

<html>
<head>
<title>Products - Error</title>
</head>
<body>

<h2>Data Entry Error</h2>

<p>You failed to correctly complete all the fields
in the form. The following problems occurred:</p>

#error.invalidFields#

</body>
</html>


Logging Errors with the cflog tag

ColdFusion provides extensive capabilities for generating, managing, and viewing log files, as described in Administering ColdFusion MX. It also provides the cflog tag which adds entries to ColdFusion logs.

ColdFusion automatically logs errors to the default logs in the following cases:

  • If you use the default error handlers
  • If a cferror handler of type Request handles the error

In all other cases, you must use the cflog tag in your error handling code to generate log entries.

The cflog tag lets you specify the following information:

  • A custom file or standard ColdFusion log file in which to write the message.
  • Text to write to the log file. This can include the values of all available error and cfcatch variables.
  • Message severity (type): Information Warning, Fatal, or Error.
  • Whether to log any of the following: application name, thread ID, system date, or system time. By default, all get logged.

For example, you could use a cflog tag in an exception error-handling page to log the error information to an application-specific log file, as in the following page:

<html>
<head>
<title>Products - Error</title>
</head>
<body>

<h2>Sorry</h2>

<p>An error occurred when you requested this page.
The error has been logged and we will work to correct the problem.
We apologize for the inconvenience. </p>

<cflog type="Error"
      file="myapp_errors"
      text="Exception error --
         Exception type: #error.type#
         Template: #error.template#,
         Remote Address: #error.remoteAddress#,
         HTTP Rerference: #error.HTTPReferer#
         Diagnositcs: #error.diagnostics#">

</body>
</html>


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cflog     type=”Error”
  file="myapp_errors"
  text="Exception error
   Exception type: #Error.type#
   Template: #Error.template#,
   Remote Address: #Error.remoteAddress#,
   Diagnositcs: #Error.diagnostics#">
When this page is processed, log an entry in the file myapp_errors.log file in the ColdFusion log directory. Identify the entry as an error message and include an error message that includes the exception type, the path of the page that caused the error, the remote address that called the page, and the error’s diagnostic message.

A log file entry similar to the following is generated if you try to call a nonexistent custom tag and this page catches the error:

"Error","web-13","12/19/01","11:29:07",MYAPP,"Exception error --
         Exception type: coldfusion.runtime.CfErrorWrapper
         Template: /MYStuff/NeoDocs/exceptiontest.cfm,
         Remote Address: 127.0.0.1,
         HTTP Rerference:
         Diagnositcs: Cannot find CFML template for custom tag testCase. Cannot find
         CFML template for custom tag testCase.  ColdFusion attempted looking in the
         tree of installed custom tags but did not find a custom tag with this
         name."

The text consists of a comma delimited list of the following entries:

  • Log entry type, specified by the cflog type attribute
  • ID of the thread that was executing
  • Date the entry was written to the log
  • Time the entry was written to the log
  • Application name, as specified by a cfapplication tag, normally in the Application.cfm file
  • The message specified by the cflog text attribute.


Handling Run-time Exceptions with ColdFusion Tags

Exceptions include any event that disrupts the normal flow of instructions in a ColdFusion page, such as failed database operations, missing include files, or developer-specified events. Ordinarily, when ColdFusion encounters an exception, it stops processing and displays an error message or an error page specified by a cferror tag or the Administrator Site-wide Error Handler setting. However, you can use ColdFusion's exception handling tags to catch and process run-time exceptions directly in ColdFusion pages.

This ability to handle exceptions directly in your application pages enables your application to do the following:

  • Respond appropriately to specific errors within the context of the current application page
  • Recover from errors whenever possible.


Exception-handling tags

ColdFusion provides the exception-handling tags listed in the following table:

Tag
Description
cftry
If any exceptions occur while processing the tag body, look for a cfcatch tag that handles the exception, and execute the code in the cfcatch tag body.
cfcatch
Execute code in the body of this tag if the exception caused by the code in the cftry tag body matches the exception type specified in this tag’s attributes.
Used in cftry tag bodies only.
cfthrow
Generate a user-specified exception.
cfrethrow
Exit the current cfcatch block and generates a new exception of the same type.
Used only in cfcatch tag bodies.


Using cftry and cfcatch tags

The cftry tag allows you to go beyond reporting error data to the user:

  • You can include code that recovers from errors so your application can continue processing without alerting the user.
  • You can create customized error messages that apply to the specific code that causes the error.

For example, you can use cftry to catch errors in code that enters data from a user registration form to a database. The cfcatch code could do the following:

  1. Retry the query, so the operation succeeds if the resource was only temporarily unavailable.
  2. If the retries fail:
  3. Display a custom message to the user
  4. Post the data to an email address so the data could be entered by company staff after the problem has been solved.

Code that accesses external resources such as databases, files, or LDAP servers where resource availability is not guaranteed is a good candidate for using Try/Catch blocks.


Try/catch code structure

In order for your code to directly handle an exception, the tags in question must appear within a cftry block. It is a good idea to enclose an entire application page in a cftry block. You then follow the cftry block with cfcatch blocks, which respond to potential errors. When an exception occurs within the cftry block, processing is thrown to the cfcatch block for that type of exception.

Here is an outline for using cftry and cfcatch to handle errors:

<cftry>
   Put your application code here ...
   <cfcatch type="exception type1">
      Add exception processing code here ...
   </cfcatch>
   <cfcatch type="exception type2">
      Add exception processing code here ...
   </cfcatch>
   .
   .
   .
   <cfcatch type="Any">
      Add exception processing code appropriate for all other exceptions
here ...
   </cfcatch>
</cftry>


Try/catch code rules and recommendations

Follow these rules and recommendations when you use cftry and cfcatch tags:

  • The cfcatch tags must follow all other code in a cftry tag body.
  • You can nest cftry blocks. For example, the following structure is valid:
    • <cftry>
   code that may cause an exception
   <cfcatch ...>
      <cftry>
         First level of exeption handling code
         <cfcatch ...>
            Second level of exception handling code
         </cfcatch
      </cftry>
   </cfcatch>
</cftry>

If an exception occurs in the first level of exception-handling code, the inner cfcatch block can catch and handle it. (An exception in a cfcatch block cannot be handled by cfcatch blocks at the same level as that block.)
  • ColdFusion always responds to the latest exception that gets raised. For example, if code in a cftry block causes an exception that gets handled by a cfcatch block, and the cfcatch block causes an exception that has no handler, ColdFusion will display the default error message for the exception in the cfcatch block, and you will not be notified of the original exception.
  • If an exception occurs when the current tag is nested inside other tags, the CFML processor checks the entire stack of open tags until it finds a suitable cftry/cfcatch combination or reaches the end of the stack.
  • Use cftry with cfcatch to handle exceptions based on their point of origin within an application page, or based on diagnostic information.
  • The entire cftry tag, including all its cfcatch tags, must be on a single CFML page. You cannot put the <cftry> start tag on one page and have the </cftry> end tag on another page.
  • For cases when acfcatch block is not able to successfully handle an error, consider using the cfrethrow tag, as described in Using the cfrethrow tag.
  • If an exception can be safely ignored, use a cfcatch tag with no body; for example:
    • <cfcatch Type = Database />
  • In particularly problematic cases, you might enclose an exception-prone tag in a specialized combination of cftry and cfcatch tags to immediately isolate the tag's exceptions.


Exception information in cfcatch blocks

Within the body of a cfcatch tag, the active exception's properties are available in the cfcatch structure.


Standard cfcatch variables

The following table describes the variables that are available in most cfcatch blocks:

Property variable
Description
cfcatch.Detail
A detailed message from the CFML compiler. This message, which can contain HTML formatting, can help to determine which tag threw the exception.
The cfcatch.Detail value is available in the CFScript cfcatch statement as the exceptionVariable parameter.
cfcatch.ErrorCode
The cfthrow tag can supply a value for this code via the errorCode attribute. For Type="Database", cfcatch.ErrorCode has the same value as cfcatch.SQLState.
Otherwise, the value of cfcatch.ErrorCode is the empty string.
cfcatch.ExtendedInfo
Custom error message information. This is returned only to cfcatch tags for which the type attribute is Application or a custom type.
Otherwise, the value of cfcatch.ExtendedInfo is the empty string.
cfcatch.Message
The exception's default diagnostic message, if one was provided. If no diagnostic message is available, this is an empty string.
The cfcatch.Messagee value is included in the value of the CFScript catch statement exceptionVariable parameter.
cfcatch.RootCause
The Java servelet exception reported by the JVM as the cause of the "root cause" of the exception.
cfcatch.TagContext
An array of structures structure containing information for each tag in the tag stack The tag stack consists of each tag that is currently open.
cfcatch.Type
The exception's type, returned as a string.

Note: If you use cfdump to display the cfcatch variable, the display does not include variables that do not have values.

The cfcatch.TagContext variable contains an array of tag information structures. Each structure represents one level of the active tag context at the time when ColdFusion detected the exception. That is, there is one structure for each tag that is open at the time of the exception. For example, if the exception occurs in a tag on a custom tag page, the tag context displays information about the called custom tag and the tag in which the error occurs.

The structure at position 1 in the array represents the currently executing tag at the time the exception was detected. The structure at position ArrayLen(cfcatch.tagContext) represents the initial tag in the stack of tags that were executing when the compiler detected the exception.

The following table lists the tagContext structure attributes:

Entry
Description
Column
Obsolete (retained for backwards compatibility). Always 0.
ID
The tag in which the exception occurred. Exceptions in CFScript are indicated by two question marks (??). All custom tags, including those called directly, are identified as CFMODULE.
Line
The line on the page in which the tag is located.
Raw_Trace
The raw Java stack trace for the error.
Template
The pathname of the application page that contains the tag.
Type
The type of page; always CFML.


Database exceptions

The following additional variables are available whenever the exception type is database:

Property variable
Description
cfcatch.NativeErrorCode
The native error code associated with this exception. Database drivers typically provide error codes to assist in the diagnosis of failing database operations. The values assumed by cfcatch.NativeErrorCode are driver-dependent.
If no error code is provided, the value of cfcatch.nativeErrorCode is -1. The value is 0 for queries of queries.
cfcatch.SQLState
The SQLState code associated with this exception. Database drivers typically provide error codes to assist in the diagnosis of failing database operations. SQLState codes are more consistent across database systems than native error codes.
If the driver does not provide an SQLState value, the value of cfcatch.SQLState is -1.
cfcatch.Sql
The SQL statement sent to the data source.
cfcatch.queryError
The error message as reported by the database driver.
cfcatch.where
If the query uses the cfqueryparam tag, query parameter name value pairs.


Expression exceptions

Property variable
Description
cfcatch.ErrNumber
An internal expression error number, valid only when type="Expression".

The following variable is only available for Expression exceptions:


Locking exceptions

The following additional information is available for exceptions related to errors that occur in cflock tags:

Property variable
Description
cfcatch.lockName
The name of the affected lock. This is set to "anonymous" if the lock name is unknown.
cfcatch.lockOperation
The operation that failed. This is set to "unknown" if the failed operation is unknown.


Missing include exceptions

The following additional variable is available if the error is caused by a missing file specified by a cfinclude tag:

Property variable
Description
cfcatch.missingFileName
The name of the missing file.


Using cftry: an example

The following example shows the cftry and cfcatch tags. It uses the CompanyInfo data source used in many of the examples in this book and a sample included file, includeme.cfm.

If an exception occurs during the cfquery statement's execution, the application page flow switches to the cfcatch type="Database" exception handler. It then resumes with the next statement after the cftry block, once the cfcatch type="Database" handler completes.

Similarly, the cfcatch type="MissingInclude" block handles exceptions raised by the cfinclude tag.

<!--- Wrap code you want to check in a cftry block --->
<cfset EmpID=3>
<cfparam name="errorCaught" default="">
<cftry>
   <cfquery name="test" datasource="CompanyInfo">
      SELECT Dept_ID, FirstName, LastName
      FROM Employee
      WHERE Emp_ID=#EmpID#
   </cfquery>

   <html>
   <head>
   <title>Test cftry/cfcatch</title>
   </head>
   <body>
   <cfinclude template="includeme.cfm">
   <cfoutput query="test">
      <p>Department: #Dept_ID#<br>
      Last Name: #LastName#<br>
      First Name: #FirstName#</p>
   </cfoutput>

<!--- Use cfcatch to test for missing included files. --->
<!---    Print Message and Detail error messages. --->
<!--- Block executes only if a MissingInclude exception is thrown. --->
   <cfcatch type="MissingInclude">
      <h1>Missing Include File</h1>
      <cfoutput>
      <ul>
         <li><b>Message:</b> #cfcatch.Message#
         <li><b>Detail:</b> #cfcatch.Detail#
         <li><b>File name:</b> #cfcatch.MissingFileName#
      </ul>
      </cfoutput>
      <cfset errorCaught = "MissingInclude">
   </cfcatch>

<!--- Use cfcatch to test for database errors.--->
<!---    Print error messages. --->
<!--- Block executes only if a Database exception is thrown. --->
   <cfcatch type="Database">
      <h1>Database Error</h1>
      <cfoutput>
      <ul>
         <li><b>Message:</b> #cfcatch.Message#
         <li><b>Native error code:</b> #cfcatch.NativeErrorCode#
         <li><b>SQLState:</b> #cfcatch.SQLState#
         <li><b>Detail:</b> #cfcatch.Detail#
         </ul>
      </cfoutput>
      <cfset errorCaught = "Database">
   </cfcatch>

<!--- Use cfcatch with type="Any" --->
<!--- to find unexpected exceptions. --->
   <cfcatch type="Any">
      <cfoutput>
         <hr>
         <h1>Other Error: #cfcatch.Type#</h1>
         <ul>
            <li><b>Message:</b> #cfcatch.Message#
            <li><b>Detail:</b> #cfcatch.Detail#
         </ul>
      </cfoutput>
      <cfset errorCaught = "General Exception">
   </cfcatch>

</body>
</html>
</cftry>

Testing the code

Use the following procedure to test the code:

  1. Make sure there is no includeme.cfm file and display the page. The cfcatch type="MissingInclude" block displays the error.
  2. Create a nonempty includeme.cfm file and display the page. If your database is configured properly, you should see an employee entry and not get any error.
  3. In the cfquery tag, change the line:
    4. FROM Employee

to:

FROM Employer

Display the page. This time the cfcatch type="Database" block displays an error message.
  4. Change Employer back to Employee.

    5. Change the cfoutput line:

    <p>Department: #Dept_ID#<br>

to:

<p>Department: #DepartmentID#<br>

Display the page. This time the cfcatch type="Any" block displays an error message indicating an expression error.
  5. Change DepartmentID back to Dept_ID and redisplay the page. The page displays properly.

    6. Open \CFusion\Log\MyAppPage.log in your text editor. You should see a header line, an initialization line, and four detail lines, similar to the following:

    "Severity","ThreadID","Date","Time","Application","Message"
"Information","web-0","11/20/01","16:27:08",,"C:\Neo\servers\default\logs\
MyAppPage.log initialized"
"Information","web-0","11/20/01","16:27:08",,"Page: /neo/MYStuff/NeoDocs/
cftryexample.cfm Error: MissingInclude"
"Information","web-1","11/20/01","16:27:32",,"Page: /neo/MYStuff/NeoDocs/
cftryexample.cfm Error: "
"Information","web-0","11/20/01","16:27:49",,"Page: /neo/MYStuff/NeoDocs/
cftryexample.cfm Error: Database"
"Information","web-1","11/20/01","16:28:21",,"Page: /neo/MYStuff/NeoDocs/
cftryexample.cfm Error: General Exception"
"Information","web-0","11/20/01","16:28:49",,"Page: /neo/MYStuff/NeoDocs/
cftryexample.cfm Error: "


Reviewing the code

The following table describes the code:

Code
Description
<cfset EmpID=3>
<cfparam name="errorCaught" default="">
Initializes the employee ID to a valid value. An application would get the value from a form or other source.
Sets the default errorCaught variable value to the empty string (to indicate no error was caught).
There is no need to put these lines in a cftry block.
<cftry>
<cfquery name="test"
      datasource="CompanyInfo">
   SELECT Dept_ID, FirstName, LastName
   FROM Employee
   WHERE Emp_ID=#EmpID#
</cfquery>
Starts the cftry block. Exceptions from here to the end of the block can be caught by cfcatch tags.
Queries the CompanyInfo database to get the data for the employee identified by the EmpID variable.
<html>
<head>
<title>Test cftry/cfcatch</title>
</head>
<body>
<cfinclude template="includeme.cfm">
<cfoutput query="test">
   <p>Department: #Dept_ID#<br>
   Last Name: #LastName#<br>
   First Name: #FirstName#</p>
</cfoutput>
Begins the HTML page. This section contains all the code that displays information if no errors occur.
Includes the includeme.cfm page.
Displays the user information record from the test query.
<cfcatch type="MissingInclude">
   <h1>Missing Include File</h1>
   <cfoutput>
   <ul>
      <li><b>Message:</b> #cfcatch.Message#
      <li><b>Detail:</b> #cfcatch.Detail#
      <li><b>File name:</b>
         #cfcatch.MissingFilename#
   </ul>
   </cfoutput>
   <cfset errorCaught = "MissingInclude">
</cfcatch>
Handles exceptions thrown when a page specified by the cfinclude tag cannot be found.
Displays cfcatch variables, including the ColdFusion basic error message, detail message, and the name of the file that could not be found.
Sets the errorCaught variable to indicate the error type.
<cfcatch type="Database">
   <h1>Database Error</h1>
   <cfoutput>
   <ul>
      <li><b>Message:</b> #cfcatch.Message#
      <li><b>Native error code:</b>
         #cfcatch.NativeErrorCode#
      <li><b>SQLState:</b> #cfcatch.SQLState#
      <li><b>Detail:</b> #cfcatch.Detail#
      </ul>
   </cfoutput>
   <cfset errorCaught = "Database">
</cfcatch>
Handles exceptions thrown when accessing a database.
Displays cfcatch variables, including the ColdFusion basic error message, the error code and SQL state reported by the databases system, and the detailed error message.
Sets the errorCaught variable to indicate the error type.
<cfcatch type="Any">
   <cfoutput>
      <hr>
      <h1>Other Error: #cfcatch.Type#</h1>
      <ul>
         <li><b>Message:</b>
#cfcatch.message#
         <li><b>Detail:</b> #cfcatch.Detail#
      </ul>
   </cfoutput>
   <cfset errorCaught = "General Exception">
</cfcatch>
Handles any other exceptions generated in the cftry block.
Since the error can occur after information has displayed (in this case, the contents of the include file), draws a line before writing the message text.
Displays the ColdFusion basic and detailed error message.
Sets the errorCaught variable to indicate the error type.
</body>
</html>
</cftry>
Ends the HTML page, then the cftry block.


Using the cfthrow tag

You can use the cfthrow tag to raise your own, custom exceptions. When you use the cfthrow tag, you specify any or all of the following information:

Attribute | Meaning
type | The type of error. It can be a custom type that has meaning only to your application, such as InvalidProductCode. You can also specify Application, the default type. You cannot use any of the predefined ColdFusion error types, such as Database or MissingTemplate.
message | A brief text message indicating the error.
detail | A more detailed text message describing the error.
errorCode | An error code that is meaningful to the application. This field is useful if the application uses numeric error codes.
extendedInfo | Any additional information of use to the application.

All of these values are optional. You access the attribute values in cfcatch blocks and Exception type error pages by prefixing the attribute with either cfcatch or error, as in cfcatch.extendedInfo. The default ColdFusion error handler displays the message and detail values in the Message pane and the remaining values in the Error Diagnostic Information pane.


Catching and displaying thrown errors

The cfcatch tag catches a custom exception when you use any of the following values for the cfcatch type attribute:

  • The custom exception type specified in the cfthrow tag.
  • A custom exception type that hierarchically matches the initial portion of the type specified in the cfthrow tag. For more information, see Custom error type name hierarchy next.
  • Application -- matches an exception that is thrown with the Application type attribute or with no type attribute.
  • Any -- matches any exception that is not caught by a more specific cfcatch tag.

Similarly, if you specify any of these types in a cferror tag, the specified error page will display information about the thrown error.

Because the cfthrow tag generates an exception, a Request error handler or the Site-wide error handler can also display these errors.


Custom error type name hierarchy

You can name custom exception types using a method that is similar to Java class naming conventions: domain name in reverse order, followed by project identifiers, as in the following example:

<cfthrow
   type="com.myCompany.myApp.Invalid_field.codeValue"
   errorcode="Dodge14B">

This fully-qualified naming method is not required; you can use shorter naming rules, for example, just myApp.Invalid_field.codeValue, or even codeValue.

This naming method is not just a convention however. The ColdFusion Server uses the naming hierarchy to select from a possible hierarchy of error handlers. For example, assume you use the following cfthrow statement:

<cfthrow type="MyApp.BusinessRuleException.InvalidAccount">

Any of the following cfcatch error handlers would handle this error:

<cfcatch type="MyApp.BusinessRuleException.InvalidAccount">
<cfcatch type="MyApp.BusinessRuleException">
<cfcatch type="MyApp">

The handler that most exactly matches handles the error. Therefore, in this case, the MyApp.BusinessRuleException.InvalidAccount handler gets invoked. However, if you used the following cfthrow tag:

<cfthrow type="MyApp.BusinessRuleException.InvalidVendorCode

the MyApp.BusinessRuleException handler receives the error.

The type comparison is no case-sensitive.


When to use cfthrow

Use the cfthrow tag when your application can identify and handle application-specific errors. One typical use for the cfthrow tag is in implementing custom data validation. The cfthrow tag is also useful for throwing errors from a custom tag page to the calling page.

For example, on a form action page or custom tag used to set a password, the application can determine whether the password entered is a minimum length, or contains both letters and number, and throw an error with a message that indicates the password rule that was broken. The cfcatch block handles the error and tells the user how to correct the problem.


Using the cfrethrow tag

The cfrethrow tag lets you create a hierarchy of error handlers. It tells ColdFusion to exit the current cfcatch block and "rethrow" the exception to the next level of error handler. Thus, if an error handler designed for a specific type of error cannot handle the error, it can rethrow the error to a more general-purpose error handler. The rethrow tag can only be used in a cfcatch tag body.


The cfrethrow tag syntax

The following pseudo-code shows how you can use the cfrethrow tag to create an error-handling hierarchy:

<cftry>
   <cftry>
      Code that might throw a database error
      <cfcatch Type="Database">
         <cfif Error is of type I can Handle>
            Handle it
         <cfelse>
            <cfrethrow>
         </cfif
      </cfcatch>
   </cftry>
   <cfcatch Type="Any">
      General Error Handling code
   </cfcatch>
</cftry>

Although this example uses a Database error as an example, you can use any cfcatch type attribute in the innermost error type.

Follow these rules when you use the rethrow tag:

  • Nest cftry tags, with one tag for each level of error handling hierarchy. Each level contains the cfcatch tags for that level of error granularity.
  • Place the most general error catching code in the outermost cftry block.
  • Place the most specific error catching code in the innermost cftry block.
  • Place the code that can cause an exception error at the top of the innermost cftry block.
  • End each cfcatch block except those in the outermost cftry block with a cfrethrow tag.


Using nested tags, cfthrow, and cfrethrow: example

The following example shows many of the techniques discussed in this chapter, including nested cftry blocks and the cfthrow and cfrethrow tags. The example includes a simple calling page and a custom tag page:

  • The calling page does little more than call the custom tag with a single attribute, a name to be looked up in a database. It does show, however, how a calling page can handle an exception thrown by the custom tag.
  • The custom tag finds all records in the CompanyInfo database with a matching last name, and returns the results in a Caller variable. If it fails to connect with the main database, it tries a backup database.


The calling page

The calling page represents a section from a larger application page. To keep things simple, the example hard-codes the name to be looked up.

<cftry>
   <cf_getEmps EmpName="Jones">
   <cfcatch type="myApp.getUser.noEmpName">
      <h2>Oops</h2>
      <cfoutput>#cfcatch.Message#</cfoutput><br>
   </cfcatch>
</cftry>
<cfif isdefined("getEmpsResult")>
   <cfdump var="#getEmpsResult#">
</cfif>


Reviewing the code

The following table describes the code:

Code
Description
<cftry>
   <cf_getEmps EmpName="Jones">
In a cftry block, calls the cf_getEmps custom tag (getEmps.cfm).
<cfcatch type="myApp.getUser.noEmpName">
      <h2>Oops</h2>
      <cfoutput>#cfcatch.Message#</cfoutput><br>
   </cfcatch>
</cftry>
If the tag throws an exception indicating that it did not receive a valid attribute, catches the exception and displays a message, including the message variable set by the cfthrow tag in the custom tag.
<cfif isdefined("getEmpsResult")>
<cfdump var="#getEmpsResult#">
</cfif>
If the tag returns a result, uses the cfdump tag to display it. (A production application would not use cfdump.)


The custom tag page

The custom tag page searches for the name in the database and returns any matching records in a getEmpsResult variable in the calling page. It includes several nested cftry blocks to handle error conditions. For a full description, see "Reviewing the code", following the example

Save the following code as getEmps.cfm in the same directory as the calling page.

<!--- If the tag didn’t pass an attribute, throw an error to be handled by
         the calling page --->
<cfif NOT IsDefined("attributes.EmpName")>
   <cfthrow Type="myApp.getUser.noEmpName"
      message = "Last Name was not supplied to the cf_getEmps tag.">
   <cfexit method = "exittag">
<!--- Have a name to look up --->
<cfelse>
<!--- Outermost Try Block --->
   <cftry>

<!--- Inner Try Block --->
      <cftry>
<!--- Try to query the main database and set a caller variable to the result --->
         <cfquery Name = "getUser" DataSource="CompanyInfo">
            SELECT *
            FROM Employee
            WHERE LastName = ’#attributes.EmpName#’
         </cfquery>
         <cfset caller.getEmpsResult = getuser>
<!--- If the query failed with a database error, check the error type
         to see if the database was found --->
         <cfcatch type= "Database">
            <cfif (cfcatch.SQLState IS "S100") OR (cfcatch.SQLState IS
               "IM002")>

<!--- If the database wasn't found, try the backup database --->
<!--- Use a third-level Try block --->
               <cftry>
                  <cfquery Name = "getUser" DataSource="CompanyInfoBackup">
                     SELECT *
                     FROM Employee
                     WHERE LastName = ’#attributes.EmpName#’
                  </cfquery>
                   <cfset caller.getEmpsResult = getuser>

<!--- If still get a database error, just return to the calling page
         without setting the caller variable. There is no cfcatch body.
         This might not be appropriate in some cases.
         The Calling page ends up handling this case as if a match was not
         found --->
                   <cfcatch type = "Database" />
<!--- Still in innermost try block. Rethrow any other errors to the next
         try block level --->
                  <cfcatch type = "Any">
                     <cfrethrow>
                  </cfcatch>
               </cftry>

<!--- Now in second level try block.
         Throw all other types of Database exceptions to the next try
            block level --->
            <cfelse>
               <cfrethrow>
            </cfif>
         </cfcatch>
<!--- Throw all other execptions to the next try block level --->
         <cfcatch type = "Any">
               <cfrethrow>
         </cfcatch>
      </cftry>

<!--- Now in Outermost try block.
       Handle all unhandled exceptions, including rethrown exceptions, by
         displaying a message and exiting to the calling page.--->
      <cfcatch Type = "Any">
         <h2>Sorry</h2>
         <p>An unexpected error happened in processing your user inquiry.
            Please report the following to technical support:</p>
         <cfoutput>
            Type: #cfcatch.Type#
            Message: #cfcatch.Message#
         </cfoutput>
         <cfexit method = "exittag">
      </cfcatch>
   </cftry>
</cfif>


Reviewing the code

The following table describes the code:

Code
Description
<cfif NOT IsDefined("attributes.EmpName")>
  <cfthrow Type="myApp.getUser.noEmpName"
    message = "Last Name was not supplied to
      the cf_getEmps tag.">
  <cfexit method = "exittag">
Makes sure the calling page specified an EmpName attribute. If not, throws a custom error that indicates the problem and exits the tag. The calling page handles the thrown error.
<cfelse>
  <cftry>
If the tag has an EmpName attribute, does the remaining work inside an outermost try block. The cfcatch block at its end handles any otherwise- uncaught exceptions.
<cftry>
  <cfquery Name = "getUser"
      DataSource="CompanyInfo">
    SELECT *
    FROM Employee
    WHERE LastName = '#attributes.EmpName#'
  </cfquery>
  <cfset caller.getEmpsResult = getuser>
Starts a second nested try block. This block catches exceptions in the database query.
If there are no exceptions, sets the calling page’s getEmpsResult variable with the query results.
<cfcatch type= "Database">
  <cfif (cfcatch.sqlstate IS "S100") OR
      (cfcatch.sqlstate IS "IM002")>
    <cftry>
      <cfquery Name = "getUser" DataSource=
         "CompanyInfoBackup"
        SELECT *
        FROM Employee
        WHERE LastName = '#attributes.EmpName#'
      </cfquery>
      <cfset caller.getEmpsResult = getuser>
If the query threw a Database error, checks to see if the error was caused by an inability to access the database (indicated by an SQLState variable value of S100 or IM002).
If the database wasn’t found, starts a third nested try block and tries accessing the backup database. This try block catches exceptions in this second database access.
If the database inquiry succeeds, sets the calling page’s getEmpsResult variable with the query results.
  <cfcatch type = "Database" />
If the second database query failed with a database error, gives up silently. Because the Database type cfcatch tag does not have a body, the tag exits. The calling page does not get a getEmpsResult variable. It cannot tell whether the database had no match or an unrecoverable database error occurred, but it does know that no match was found.
  <cfcatch type = "Any">
    <cfrethrow>
  </cfcatch>
</cftry>
If the second database query failed for any other reason, throws the error up to the next try block.
Ends the innermost try block
  <cfelse>
    <cfrethrow>
  </cfif>
</cfcatch>
In the second try block, handles the case in which the first database query failed for a reason other than a failure to find the database.
Rethrows the error up to the next level, the outermost try block.
  <cfcatch type = "Any">
    <cfrethrow>
  </cfcatch>
</cftry>
In the second try block, catches any errors other exceptions and rethrows them up to the outermost try block.
Ends the second try block.
    <cfcatch Type = "Any">
      <h2>Sorry</h2>
      <p>An unexpected error happened in processing
         your user inquiry.
        Please report the following to technical
support:</p>
      <cfoutput>
        Type: #cfcatch.Type#
        Message: #cfcatch.Message#
      </cfoutput>
    <cfexit method = "exittag">
    </cfcatch>
  </cftry>
</cfif>
In the outermost try block, handles any exceptions by displaying an error message that includes the exception type and the exception’s error message. Because there was no code to try that is not also in a nested try block, this cfcatch tag handles only errors that are rethrown from the nested blocks.
Exits the custom tag and returns to the calling page.
Ends the catch block, try block, and initial cfif block.


Testing the code

To test the various ways errors can occur and be handled in this example, try the following:

  • In the calling page, change the attribute name to any other value; for example, My Attrib. Then change it back.
  • In the first cfquery tag, change the data source name to an invalid data source; for example, NoDatabase.
  • With an invalid first data source name, change the data source in the second cfquery tag to CompanyInfo.
  • Insert cfthrow tags throwing custom exculpations in various places in the code and observe the effects.
Previous


Using Persistent Data and Locking

ColdFusion provides several variable scopes in which data persists past the life of a single request. These are the Client, Application, Session, and Server scopes. These scopes let you save data over time and share data between pages and even applications. (This chapter refers to these scopes as persistent scopes.) In particular, you can use the Client and Session scopes to maintain information about a user across multiple requests.

ColdFusion lets you lock access to sections of code to ensure that ColdFusion does not attempt to run the code, or access the data that it uses, simultaneously or in an unpredictable order. This locking feature is important for ensuring the consistency of all shared data, including data in external sources in addition to data in persistent scopes.

This chapter describes how to use persistent scopes to develop an application and how to use locking to ensure data consistency.

Contents
  • About persistent scope variables
  • Managing the client state
  • Configuring and using Client variables
  • Configuring and using Session variables
  • Configuring and using Application variables
  • Using Server variables
  • Locking code with cflock
  • Examples of cflock
Next


About persistent scope variables

ColdFusion provides four variable scopes, described in the following table, that let you maintain data that must be available to multiple applications or users or must last beyond the scope of the current request.

Variable cope
Description
Client
Contains variables that are available for a single client browser over multiple browser sessions in an application. For information about browser sessions, see, What is a session?.
Useful for client-specific information, such as client preferences, that you want to store for a significant period of time.
Data is stored as cookies, database entries, or Registry values. Client variables can time out after an extended period.
Although do not have to use the Client scope prefix in the variable name, code that uses the prefix is more efficient and easier to maintain.
Session
Contains variables that are available for a single client browser for a single browser session in an application.
Useful for client-specific information, such as shopping cart contents, that you want to persist while the client is visiting your application.
Data is stored in memory and times out after a period of inactivity or when the server shuts down.
ColdFusion Administrator lets you select between two kinds of session management, Standard ColdFusion Session management and J2EE session management. For information about types of session management, see, ColdFusion and J2EE session management
You must use the Session scope prefix in the variable name.
Application
Contains variables that are available to all pages in an application for all clients.
Useful for application-specific information, such as contact information, that can vary over time and should be stored in a variable.
Data is stored in memory and times out after a period of inactivity or when the server shuts down.
You must use the Application scope prefix in the variable name.
Server
Contains variables that are available to all applications in a server and all clients.
Useful for information that applies to all pages on the server, such as an aggregate page-hit counter.
Data is stored in memory. The variables do not time out, but you can delete variables you create, and all server variables are automatically deleted when the server stops running.
You must use the Server scope prefix in the variable name.

The following sections provide information that is common to all or several of these variables. Later sections describe how to use the Client, Session, Application, and Server scopes in your applications, and provide detailed information about locking code.


ColdFusion persistent variables and ColdFusion structures

All persistent scopes are available as ColdFusion structures. As a result, you can use ColdFusion structure functions to access and manipulate Client, Session, Application, and Server scope contents. This chapter does not cover using these functions in detail, but does mention features or limitations that apply to specific scopes.

Note: Although you can use the StructClear function to clear your data from the Server scope, the function does not delete the names of the variables, only their values, and it does not delete the contents of the Server.os and Server.ColdFusion structures. Using the StructClear function to clear the Session, or Application scope clears the entire scope, including the built-in variables. Using the StructClear function to clear the Client scope clears the variables from the server memory, but does not delete the stored copies of the variables.


ColdFusion persistent variable issues

Variables in the Session, Application, and Server scopes are kept in ColdFusion server memory. This storage method has several implications:

  • All variables in these scopes are lost if the server stops running.
  • Variables in these scopes are not shared by servers in a cluster.
  • To ensure data consistency, you must lock access to all code that changes variables in these scopes and all code that reads variables in these scopes with values that can change.

Additionally, you must be careful when using Client variables in a server cluster, where an applications can run on multiple servers.

Note: If you use J2EE session management and configure the J2EE server to retain session data between server restarts, ColdFusion retains Session variables between server restarts.


Using variables in clustered systems

Because memory variables are stored in memory, they are not available to all servers in a cluster. As a result, you generally do not use Session, Application, or Server scope variables in clustered environment. However, you might use these scope variables in a clustered system in the following circumstances:

  • Many clustering systems, including ClusterCats support “sticky” sessions, in which the clustering system ensures that each user session remains on a single server. In this case, you can use Session variables as you would on a single server.
  • You can use Application and Server scope variables in a cluster for write-once variables that are consistently set, for example, from a database.

To use Client variables on a clustered system, store the variables as cookies or in a database that is available to all servers. If you use database storage, select the Purge Data for Clients that Remain Unvisited option in the ColdFusion Administrator Client Variables Add/Edit Client Store page on one server only.

For more information on using Client and Session variables in clustered systems, see Managing client identity information in a clustered environment.


Locking memory variables

Because ColdFusion is a multithreaded system in which multiple requests can share Session, Application, and Server scope variables, it is possible for two or more requests to try to access and modify data at the same time. ColdFusion runs in a J2EE environment, which prevents simultaneous data access, so multiple requests do not cause severe system errors. However, such requests can result in inconsistent data values, particularly when a page might change more than one variable.

To prevent data errors with Session, Application, and Server variables, lock code that writes and reads data in these scopes. For more information, see Locking code with cflock.


Managing the client state

Because the Web is a stateless system, each connection that a browser makes to a web server is unique to the web server. However, many applications must keep track of users as they move through the pages within the application. This is the definition of client state management.

ColdFusion provides tools to maintain the client state by seamlessly tracking variables associated with a browser as the user moves from page to page within the application. You can use these variables in place of other methods for tracking client state, such as URL parameters, hidden form fields, and HTTP cookies.


About Client and Session variables

ColdFusion provides two tools for managing the client state: Client variables and Session variables. Both types of variables are associated with a specific client, but you manage and use them differently, as described in the following table:

Variable type
Description
Client
Data is saved as cookies, database entries, or Registry entries. Data is saved between server restarts, but is initially accessed and saved more slowly than data stored in memory.
Each type of data storage has its own time-out period. You can specify the database and Registry data time-outs in ColdFusion Administrator. ColdFusion sets Cookie client variables to expire after approximately 10 years.
Data is stored on a per-user and per-application basis. For example, if you store Client variables as cookies, the user has a separate cookie for each ColdFusion application provided by a server.
Client variables must be simple variables, such as numbers, dates, or strings. They cannot be arrays, structures, query objects, or other objects.
Client variable names can include periods. For example, My.ClientVar is a valid name for a simple Client variable. Avoid such names, however, to ensure code clarity,
You do not have to prefix Client variables with the scope name when you reference them, However, if you do not use the Client prefix, you might unintentionally refer to a variable with the same name in another scope. Using the prefix also optimizes performance and increases program clarity.
You do not lock code that uses Client variables.
You can use Client variables that are stored in cookies or a common database in clustered systems.
Session
Data is stored in memory so it is accessed quickly.
Data is lost when the client browser is inactive for a time-out period. You specify the time-out in the ColdFusion Administrator and Application.cfm.
As with Client variables, data is available to a single client and application only.
Variables can store any ColdFusion data type.
You must prefix all variable names with the Session scope name.
Lock code that uses Session variables to ensure data integrity.
You can use Session variables in clustered systems only if the systems support “sticky” sessions, where a session is limited to a single server.

Session variables are normally better than Client variables for values that need to exist for only a single browser session. You should reserve Client variables for client-specific data, such as client preferences that you want available for multiple browser sessions.


Maintaining client identity

Because the web is a stateless system, client management requires some method for maintaining knowledge of the client between requests. Normally you do this using cookies, but you can also do it by passing information between application pages. The following sections describe how ColdFusion maintains client identity in a variety of configurations and environments, and discuss issues that can arise with client state management.


About client identifiers

To use Client and Session variables, ColdFusion must be able to identify the client. It normally does so by setting the following two cookie values on the client’s system:

  • CFID A sequential client identifier
  • CFToken A random-number client security token

These cookies uniquely identify the client to ColdFusion, which also maintains copies of the variables as part of the Session and Client scopes. You can configure your application so that it does not use client cookies, but in this case, you must pass these variables to all the pages that your application calls. For more information about maintaining client and session information without using cookies, see Using Client and Session variables without cookies.

You can configure ColdFusion MX to use J2EE servlet session management instead of ColdFusion session management for Session variables. This method of session management does not use CFID and CFToken values, but does use a client-side jsessionid session management cookie. For more information on using J2EE session management, see ColdFusion and J2EE session management.


Using Client and Session variables without cookies

Often, users disable cookies in their browsers. In this case, ColdFusion cannot maintain the client state automatically. You can use Client or Session variables without using cookies, by passing the client identification information between application pages. However, this technique has significant limitations, as follows:

  • Client variables are effectively the same as Session variables, except that they leave unusable data in the client data store.

    • Because the client’s system does not retain any identification information, the next time the user logs on, ColdFusion cannot identify the user with the previous client and must create a new client ID for the user. Any information about the user from a previous session is not available, but remains in client data storage until ColdFusion deletes it. If you clear the Purge Data for Clients that Remain Unvisited option in ColdFusion Administrator, ColdFusion never deletes this data.

    Therefore, do not use Client variables, if you do not require users to enable cookies. To retain client information without cookies, require users to login with a unique ID. You can then save user-specific information in a database with the user’s ID as a key.

  • ColdFusion creates a new session each time the user requests a page directly in the browser, because the new request contains no state information to indicate the session or client.

Note: You can prevent ColdFusion from sending client information to the browser as cookies by setting the setClientCookies attribute of the cfapplication tag to No.

To use ColdFusion Client or Session variables without using cookies, each page must pass the CFID and CFToken values to any page that it calls as part of the request URL. If a page contains any HTML href a= links, cflocation tags, form tags, or cfform tags the tags must pass the CFID and CFToken values in the tag URL. To use J2EE session management, you must pass the jsessionid value in page requests. To use ColdFusion Client variables and J2EE session variables, you must pass the CFID, CFToken, and jsessionid values in URLs.

ColdFusion provides the URLSessionFormat function, which does the following:

  • If the client does not accept cookies, automatically appends all required client identification information to a URL.
  • If the client accepts cookies, does not append the information.

The URLSessionFormat function automatically determines which identifiers are required, and sends only the required information. It also provides a more secure and robust method for supporting client identification than manually encoding the information in each URL, because it only sends the information that is required, when it is required, and it is easier to code.

To use the URLSessionFormat function, enclose the request URL in the function. For example, the following cfform tag posts a request to another page and sends the client identification, if required:

<cfform method="Post" action="#URLSessionFormat("MyActionPage.cfm")#>

Tip: If you use the same page URL in multiple URLSessionFormat functions, you can gain a small performance improvement and simplify your code if you assign the formatted page URL to a variable, for example:

<cfset myEncodedURL=URLSessionFormat(MyActionPage.cfm)>
<cfform method="Post" action="#myEncodedURL#">


Client identifiers and security

You must consider The following client identifier issues can have security implications:

  • Ensuring the uniqueness and complexity of the CFToken identifier
  • Limiting the availability of Session identifiers

The next sections discuss these issues.


Ensuring CFToken uniqueness and security

By default, ColdFusion uses an eight-digit random number in the CFToken identifier. This CFToken format provides a unique, secure identifier for users under most circumstances. (In ColdFusion MX, the method for generating this number uses a cryptographic-strength random number generator that is seeded only when the server starts.)

However, you can enable the ColdFusion Administrator Settings page to produce a more complex CFToken identifier. If you enable the Use UUID for cftoken option, ColdFusion creates the CFToken value by prepending a 16-digit random hexadecimal number to a ColdFusion UUID. The resulting CFToken identifier looks similar to the following:

3ee6c307a7278c7b-5278BEA6-1030-C351-3E33390F2EAD02B9


Providing Session security

ColdFusion uses the same client identifiers for the Client scope and the standard Session scope. Because the CFToken and CFID values are used to identify a client over a period of time, they are normally saved as cookies on the user’s browser. These cookies persist until the client’s browser deletes them, which can be a considerable length of time. As a result, hackers could have more access to these variables than if ColdFusion used different user identifiers for each session.

A hacker who has the user’s CFToken and CFID cookies could gain access to user data by accessing a web page during the user’s session using the stolen CFToken and CFID cookies. While this scenario is unlikely, it is theoretically possible.

You can remove this vulnerability by selecting the Use J2EE Session Variables option on the ColdFusion Administrator Memory Variables page. The J2EE session management mechanism creates a new session identifier for each session, and does not use either the CFToken or the CFID cookie value.


Managing client identity information in a clustered environment

To maintain your application's client identity information in a clustered server environment, you must specify the cfapplication setdomaincookies attribute in your Application.cfm page.

The setdomaincookies attribute specifies that the server-side copies of the CFID and CFToken variables used to identify the client to ColdFusion are stored at the domain level (for example, .macromedia.com). If CFID and CFToken variable combinations already exist on each host in the cluster, ColdFusion migrates the host-level variables on each cluster member to the single, common domain-level variable. Following the setting or migration of host-level cookie variables to domain-level variables, ColdFusion creates a new cookie variable (CFMagic) that tells ColdFusion that domain-level cookies have been set.

If you use Client variables in a clustered system, you must also use a database or cookies to store the variables.


Configuring and using Client variables

Use client variables for data that is associated with a particular client and application and that must be saved between user sessions. Use Client variables for long-term information such as user display or content preferences.


Enabling Client variables

To enable Client variables, you must set the cfapplication tag clientmanagement attribute to Yes on every page. Because the Application.cfm file is included in all of the application's pages, you enable client management in the cfapplication tag, at the beginning of the Application.cfm file. For example, to enable Client variables in an application named SearchApp, you use the following line in the application’s Application.cfm page:

<cfapplication NAME="SearchApp" clientmanagement="Yes">


Choosing a Client variable storage method

By default, Coldfusion stores Client variables in the Registry. In most cases, however, it is more appropriate to store the information as client cookies or in a SQL database.

The ColdFusion Administrator Client Variables page controls the default Client variable location. You can override the default location by specifying a clientStorage attribute in the cfapplication tag.

You can specify the following values in the clientStorage attribute:

  • Registry(default)
  • Name of a data source configured in ColdFusion Administrator
  • Cookie

Generally, it is most efficient to store Client variables in a database. Although the Registry option is the default, the Registry has significant limitations for client data storage. The Registry cannot be used in clustered systems and its use for Client variables on UNIX is not supported in ColdFusion MX.


Using cookie storage

When you set the cfapplication tag clientstorage="Cookie" attribute, the cookie that ColdFusion creates has the application's name. Storing client data in a cookie is scalable to large numbers of clients, but this storage mechanism has some limitations. In particular, if the client turns off cookies in the browser, Client variables do not work.

Consider the following additional limitations before implementing cookie storage for Client variables:

  • Some browsers allow only 20 cookies to be set from a particular host. ColdFusion uses two of these cookies for the CFID and CFToken identifiers, and also creates a cookie named cfglobals to hold global data about the client, such as HitCount, TimeCreated, and LastVisit. This limits you to 17 unique applications per client-host pair.
  • Some browsers set a size limit of 4K bytes per cookie. ColdFusion encodes non alphanumeric data in cookies with a URL encoding scheme that expands at a 3-1 ratio, which means you should not store large amounts of data per client. ColdFusion throws an error if you try to store more than 4,000 encoded bytes of data for a client.


Configuring database storage

When you specify a database for Client variable storage, do not always have to manually create the data tables that store the client variables.

If ColdFusion can identify that the database you are using supports SQL creation of database tables, you only need to create the database in advance. When you click the Add button on the Select Data Source to Add as Client Store box of the Memory Variables page, ColdFusion Administrator displays a Add/Edit Client Store page which contains a Create Client Database Tables selection box. Select this option to have ColdFusion create the necessary tables in your database. (The option does not appear if the database already has the required tables.)

If your database does not support SQL creation of tables, or if you are using the ODBC socket [Macromedia] driver to access your database, you must use your database tool to create the Client variable tables. Create the following two tables:

The CDATA table must have the following columns:

Column | Data type
cfid | CHAR(64), TEXT, VARCHAR, or any data type capable of taking variable length strings up to 64 characters
app | CHAR(64), TEXT, VARCHAR, or any data type capable of taking variable length strings up to 64 characters
data | MEMO, LONGTEXT, LONG VARCHAR, or any data type capable of taking long, indeterminate-length strings

The CGLOBAL table must have the following columns:

Column | Data type
cfid | CHAR(64), TEXT, VARCHAR, or any data type capable of taking variable length strings up to 64 characters
data | MEMO, LONGTEXT, LONG VARCHAR, or any data type capable of taking long, indeterminate-length strings
lvisit | TIMESTAMP, DATETIME, DATE, or any data type that stores date and time values

Note: Different databases use different names for their data types. The names in the preceding tables are common, but your database may use other names.

To improve performance, you should also create indexes when you create these tables. For the CDATA table, index these cfid and app columns. For the CGLOBAL table, index the cfid column.


Specifying Client variable storage in the Application.cfm file

The cfapplication tag clientStorage attributes lets you override the default Client variable storage application location. The following line tells ColdFusion to store the client variables in the mydatasource data source:

<cfapplication name"SearchApp"
   clientmanagement="Yes"
   clientstorage="mydatasource">


Using Client variables

When you enable Client variables for an application, you can use them to keep track of long-term information that is associated with a particular client.

Client variables must be simple data types: strings, numbers, lists, Booleans, or date and time values. They cannot be arrays, record sets, XML objects, query objects, or other objects. If you must store a complex data type as a Client variable, you can use the cfwddx tag to convert the data to WDDX format (which is represented as a string), store the WDDX data, and use the cfwddx tag to convert the data back when you read it. For more information on using WDDX, see Using WDDX.


Creating a Client variable

To create a Client variable and set its value, use the cfset or cfparam tag and use the Client scope identifier as a variable prefix; for example:

<cfset Client.FavoriteColor="Red">

After you set a Client variable this way, it is available for use within any page in your application that is accessed by the client for whom the variable is set.

The following example shows how to use the cfparam tag to check for the existence of a client parameter and set a default value if the parameter does not already exist:

<cfparam name="Client.FavoriteColor" default="Red">


Accessing and changing Client variables

You use the same syntax to access a Client variable as for other types of variables. You can use Client variables anywhere you use other ColdFusion variables.

To display the favorite color that has been set for a specific user, for example, use the following code:

<cfoutput>
   Your favorite color is #Client.FavoriteColor#.
</cfoutput>

To change the client’s favorite color, for example, use code such as the following:

<cfset Client.FavoriteColor = Form.FavoriteColor>


Standard Client variables

The Client scope has the following built-in, read-only variables that your application can use:

Variable
Description
Client.CFID
The client ID, normally stored on the client system as a cookie.
Client.CFToken
The client security token, normally stored on the client system as a cookie.
Client.URLToken
A combination of the CFID and CFToken values, in the form CFID=IDNum&CFTOKEN=tokenNum. This variable is useful if the client does not support cookies and you must pass the CFID and CFToken variables from page to page.
Client.HitCount
The number of page requests made by the client.
Client.LastVisit
The last time the client visited the application.
Client.TimeCreated
The time the CFID and CFToken variables that identify the client to ColdFusion were first created.

Note: ColdFusion allows you to delete or change the values of the built-in Client variables. As a general rule, avoid doing so.

You use the Client.CFID, Client.CFToken, and Client.URLToken variables if your application supports browsers that do not allow cookies. For more information on supporting browsers that do not allow cookies, see Using Client and Session variables without cookies.

You can use the Client.HitCount and time information variables to customize behavior that depends on how often users visit your site and when they last visited. For example, the following code shows the date of a user's last visit to your site:

<cfoutput>
Welcome back to the Web SuperShop. Your last
visit was on #DateFormat(Client.LastVisit)#.
</cfoutput>


Getting a list of Client variables

To obtain a list of the custom client parameters associated with a particular client, use the GetClientVariablesList function, as follows:

<cfoutput>#GetClientVariablesList()#</cfoutput>

The GetClientVariablesList function returns a comma-separated list of the names of the Client variables for the current application. The standard system-provided Client variables (CFID, CFToken, URLToken, HitCount, TimeCreated, and LastVisit) are not returned in the list.


Deleting Client variables

To delete a Client variable, use the StructDelete function or the DeleteClientVariable function. For example, the following lines are equivalent:

<cfset IsDeleteSuccessful=DeleteClientVariable("MyClientVariable")>
<cfset IsDeleteSuccessful=StructDelete(Client, "MyClientVariable")>

The Client Variables page of ColdFusion Administrator lets you set a time-out period of inactivity after which ColdFusion removes Client variables stored in either the Registry or a data source. (The default value is 10 days for Client variables stored in the Registry, and 90 days for Client variables stored in a data source.)

Note: You cannot delete the system-provided Client variables (CFID, CFToken, URLToken, HitCount, TimeCreated, and LastVisit).


Using Client variables with cflocation

If you use the cflocation tag to redirect ColdFusion to a path that ends with .dbm or .cfm, the Client.URLToken variable is automatically appended to the URL. You can prevent this behavior by adding the attribute addtoken="No" to the cflocation tag.


Caching Client variable

When ColdFusion reads or writes Client variables, it caches the variables in memory to help decrease the overhead of accessing the client data. As a result, ColdFusion only accesses the client data store when you read its value for the first time or, for values you set, when the request ends. Additional references to the client variable use the cached value in ColdFusion memory, thereby processing the page more quickly.


Exporting the Client variable database

If your Client variable database is stored in the Windows system Registry and you need to move it to another machine, you can export the Registry key that stores your Client variables and take it to your new server. The system Registry lets you export and import Registry entries.

To export your Client variable database from the Registry in Windows:

  1. Open the Registry editor.
  2. Find and select the following key:
    3. HKEY_LOCAL_MACHINE\SOFTWARE\Macromedia\ColdFusion\CurrentVersion\
Clients
  3. On the Registry menu, click Export Registry File.
  4. Enter a name for the registry file.

After you create a registry file, you can copy it to a new machine and import it by clicking Import Registry File on the Registry editor Registry menu.

Note: On UNIX systems, the Registry entries are kept in /opt/coldfusion/registry/cf.registry, a text file that you can copy and edit directly.


Configuring and using Session variables

Use Session variables when you need the variables for a single site visit or set of requests. For example, you might use Session variables to store a user's selections in a shopping cart application. (Use Client variables if you need a variable in multiple visits.)

Caution:To preserve data integrity, put code that uses Session variables inside cflock tags. For information on using cflock tags see Locking code with cflock.


What is a session?

A session refers to all the connections that a single client might make to a server in the course of viewing any pages associated with a given application. Sessions are specific to both the individual user and the application. As a result, every user of an application has a separate session and has access to a separate set of Session variables.

This logical view of a session begins with the first connection to an application by a client and ends after that client's last connection. However, because of the stateless nature of the web, it is not always possible to define a precise point at which a session ends. A session should end when the user finishes using an application. In most cases, however, a web application has no way of knowing if a user has finished or is just lingering over a page.

Therefore, sessions always terminate after a time-out period of inactivity. If the user does not access a page of the application within this time-out period, ColdFusion interprets this as the end of the session and clears any variables associated with that session.

The default time-out for Session variables is 20 minutes. You can change the default time-out on the Memory Variables page of ColdFusion Administrator Server tab.

You can also set the time-out period for Session variables inside a specific application (thereby overruling the Administrator default setting) by using the cfapplication tag sessionTimeout attribute. However, you cannot use the cfapplication tag to set a time-out value that is greater than the maximum session time-out value set on the Administrator Memory Variables page.

Your application can also manually end a session, for example when a user logs out.


ColdFusion and J2EE session management

The ColdFusion server can use either of the following types of session management:

  • ColdFusion session management
  • J2EE servlet session management

ColdFusion session management uses the same client identification method as ColdFusion client management. When you use ColdFusion session management, Session variables are not available to JSP pages or Java servlets that you call from your ColdFusion pages.

J2EE session management uses a session-specific session identifier, jsessionid, which is created afresh at the start of each session. With J2EE session management, you can share Session variables between ColdFusion pages and JSP pages or Java servlets that you call from the ColdFusion pages. Therefore, consider using J2EE session management in any of the following cases:

  • You want to maximize session security, particularly if you also use Client variables
  • You want to share Session variables between ColdFusion pages and JSP pages or servlets in a single application.
  • You want to be able to manually terminate a session while maintaining the client identification cookie for use by the Client scope.


Configuring and enabling Session variables

To use Session variables, you must enable them in both of the following places:

  • ColdFusion Administrator
  • The active cfapplication tag

ColdFusion Administrator and the cfapplication tag also provide facilities for configuring Session variable behavior, including the variable time-out.


Selecting and enabling Session variables in ColdFusion Administrator

To use Session variables, they must be enabled on the ColdFusion Administrator Memory Variables page. (They are enabled by default.) You can also use the Administrator Memory Variables page to do the following:

  • Select to use ColdFusion session management (the default) or J2EE session management.
  • Change the default session time-out. The cfapplication tag can override this value. The default value for this time-out is 20 minutes.
  • Specify a maximum session time-out. The cfapplication tag cannot set a time-out greater than this value. The default value for this time-out is two days.


Enabling Session variables in your application

You must also enable Session variables in the cfapplication tag in your Application.cfm file. Do the following in the Application.cfm file to enable Session variables:

  • Set sessionManagement="Yes"
  • Use the name attribute to specify the application's name.
  • Optionally, use the sessionTimeout attribute to set an application-specific session time-out value. Use the CreateTimeSpan function to specify the number of days, hours, minutes, and seconds for the time-out.

The following sample code enables session management for the GetLeadApp application and sets the Session variables to time out after a 45-minute period of inactivity:

<cfapplication name="GetLeadApp"
sessionmanagement="Yes"
sessiontimeout=#CreateTimeSpan(0,0,45,0)#>


Storing session data in Session variables

Session variables are designed to store session-level data. They are a convenient place to store information that all pages of your application might need during a user session, such as shopping cart contents or score counters.

Using Session variables, an application can initialize itself with user-specific data the first time a user accesses one of the application’s pages. This information can remain available while that user continues to use that application. For example, you can retrieve information about a specific user’s preferences from a database once, the first time a user accesses any page of an application. This information remains available throughout that user’s session, thereby avoiding the overhead of retrieving the preferences repeatedly.


Standard Session variables

If you use ColdFusion Session variables, the Session scope has four built-in, read-only variables that your application can use. If you use J2EE session management, the Session scope has two built-in variables. Generally, you use these variables in your ColdFusion pages only if your application supports browsers that do not allow cookies. For more information on supporting browsers that do not allow cookies, see Using Client and Session variables without cookies. The following table describes the built-in Session variables.

Variable
Description
Session.CFID
ColdFusion session management only: the client ID, normally stored on the client system as a cookie.
Session.CFToken
ColdFusion session management only: the client security token, normally stored on the client system as a cookie.
Session.URLToken
ColdFusion session management: a combination of the CFID and CFToken values in the form CFID=IDNum&CFTOKEN=tokenNum. Use this variable if the client does not support cookies and you must pass the CFID and CFToken variables from page to page.
J2EE session management: the string jsessionid= followed by the J2EE session ID.
Session.SessionID
A unique identifier for the session.
ColdFusion session management: the application name and CFID and CFToken values.
J2EE session management: the jsessionid value.

Note: ColdFusion allows you to delete or change the values of the built-in Session variables. As a general rule, avoid doing so.

If you enable Client variables and ColdFusion session management, ColdFusion uses the same values for the Client and Session scope CFID, CFToken, and URLtoken variables. ColdFusion gets the values for these variables from the same source, the client’s CFID and CFTOKEN cookies.

If you use J2EE session management, the Session scope does not include the Session.CFID or Session.CFToken variables, but does include the Session.URLToken and Session.SessionID variables. In this case, the Session.SessionID is the J2EE session ID and Session.URLToken consists of the string jsessionid= followed by the J2EE session ID.


Getting a list of Session variables

Use the StructKeyList function to get a list of Session variables, as follows:

<cflock timeout=20 scope="Session" type="Readonly">
   <cfoutput> #StructKeyList(Session)# </cfoutput>
</cflock>

Caution:Always put code that accesses Session variables inside cflock tags.


Creating and deleting Session variables

Use a standard assignment statement to create a new session variable, as follows:

<cflock timeout=20 scope="Session" type="Exclusive">
   <cfset Session.ShoppingCartItems = 0>
</cflock>

Use the structdelete tag to delete a session variable; for example:

<cflock timeout=20 scope="Session" type="Exclusive">
   <cfset StructDelete(Session, "ShoppingCartItems")>
</cflock>

Note: If you set Session variables on a CFML template that uses the cflocation tag, ColdFusion may not set the variables. For more information, see Macromedia TechNote 22712 at http://www.macromedia.com/v1/Handlers/index.cfm?ID=22712&Method=Full.


Accessing and changing Session variables

You use the same syntax to access a Session variable as for other types of variables. However, you must lock any code that accesses or changes Session variables.

For example, to display the number of items in a user’s shopping cart, use favorite color that has been set for a specific user, for example, use the following code:

<cflock timeout=20 scope="Session" type="Exclusive">
   <cfoutput>
      Your shopping cart has #Session.ShoppingCartItems# items.
   </cfoutput>
</cflock>

To change increase the number of items in the shopping cart, use the following code:

<cflock timeout=20 scope="Session" type="Exclusive">
   <cfset Session.ShoppingCartItems = Session.ShoppingCartItems + 1>
</cflock>


Ending a session

If you use J2EE session management, the session and all Session variables are deleted, when the user closes the browser.

If you use ColdFusion session management and do not explicitly terminate a session, for example when a user logs out, the session variables remain in ColdFusion server memory until the session time-out period elapses. If you store sensitive data, such as personally identifiable user information, in Session variables, you should clear the data from the Session structure when the user logs out.

You can expire a session by using the cfapplication tag and setting the sessiontimeout attribute 0. The cfapplication tag must also reset all other attributes to the desired settings, as follows:

<cfapplication
   name="MyApp"
   clientmanagement="Yes"
   applicationtimeout="#CreateTimeSpan(0, 0, 0, 30)#"
   sessionmanagement="Yes"
   sessiontimeout=#CreateTimeSpan(0, 0, 0, 0)# >

To save processing time, ColdFusion deletes expired session variables every 10 seconds. As a result, the session may continue to exist for up to 10 seconds after ColdFusion executes your code.


Configuring and using Application variables

Application variables are available to all pages within an application, that is, pages that have the same application name. Because Application variables are persistent, you easily can pass values between pages. You can use Application variables for information including the application name, background color, data source names, or contact information.

You set the application name in the cfapplication tag, normally on your application’s Application.cfm page. The application name is stored in the Application.applicationName variable.

Unlike Client and Session variables, Application variables do not require that a client name (client ID) be associated with them. They are available to any clients that use pages in the application.

Caution:To preserve data integrity, put code that uses Application variables inside cflock tags. For information on using cflock tags see Locking code with cflock.

The following sections describe how to configure and use Application variables.


Configuring and enabling Application variables

To use Application variables, do the following:

  • Ensure that they are enabled in ColdFusion Administrator. (They are enabled by default.)
  • Specify the application name in the cfapplication tag for the current page.

    • Note: ColdFusion supports unnamed applications for compatibility with J2EE applications. For more information see Unnamed ColdFusion Application and Session scopes.

ColdFusion Administrator also lets you specify the following information:

  • A default variable time-out. If all pages in an application are inactive for the time-out period, ColdFusion deletes all the Application variables. The cfapplication tag can override this value for a specific application. The default value for this time-out is two days.
  • A maximum time-out. The cfapplication tag cannot set a time-out greater than this value. The default value for this time-out is two days.

You can set the time-out period for Application variables within a specific application by using the applicationTimeout attribute of the cfapplication tag.


Storing application data in Application variables

Application variables are a convenient place to store information that all pages of your application might need, no matter which client is running that application. Using Application variables, an application could, for example, initialize itself when the first user accesses any page of that application. This information can then remain available indefinitely, thereby avoiding the overhead of repeated initialization.

Because the data stored in Application variables is available to all pages of an application, and remains available until a specific period of inactivity passes or the ColdFusion Server shuts down, Application variables are convenient for application-global, persistent data.

However, because all clients running an application see the same set of Application variables, these variables are not appropriate for client-specific or session-specific information. To target variables for specific clients, use Client or Session variables.


Using Application variables

Generally, Application variables should hold information that you write infrequently. In most cases, the values of these variables are set once, most often when an application first starts. Then the values of these variables are referenced many times throughout the life of the application or the course of a session.

To preserve data integrity, you must put all code that writes to Application scope variables or reads Application scope variables with data that can change inside cflock tags.

Because each Application scope variable is shared in memory by all requests in the application, these variables can become bottlenecks if used inappropriately. Whenever a request is reading or writing an Application scope variable, any other requests that use the variable must wait until the code accessing the variable completes. This problem is increased by the processing time required for locking. If many users access the application simultaneously and you use Application scope variables extensively, your application performance may degrade. If your application uses many Application variables, consider whether the variables must be in the Application scope or whether they can be Session or Request scope variables.

The application scope has one built-in variable, Application.applicationName, which contains the application name you specify in the cfapplication tag.

You access and manipulate Application variables the same way you use Session variables, except that you use the variable prefix Application, not Session, and specify Session as the lock scope. For examples of using Session variables see Creating and deleting Session variables and Accessing and changing Session variables.

For information on locking write-once read-many Application variables efficiently, see Locking Application variables efficiently


Using Server variables

Server variables are associated with a single ColdFusion Server. They are available to all applications that run on the server. Use Server variables for data that must be accessed across clients and applications, such as global server hit counts.

Server variables do not time out, but they are lost when the server shuts down. You can delete Server variables.

Server variables are stored on a single server. As a result, you should not use Server variables if you use ColdFusion on a server cluster.

You access and manipulate Server variables the same way use Session and Application variables, except you use the variable prefix Server.

Caution:To preserve data integrity, put code that uses Server variables inside cflock tags. You do not have to lock access to built-in Server variables.

ColdFusion provides the following standard built-in read-only Server variables:

Variable | Description
Server.ColdFusion.AppServer | The name of the J2EE application server ColdFusion is using. For ColdFusion MX Server editions, which have an integrated application server, the name is JRun4.
Server.ColdFusion.Expiration | The date, in ODBC date format, on which the ColdFusion Server license expires. (A null string in all but trial versions of ColdFusion.)
Server.ColdFusion.ProductLevel | The server product level, such as Enterprise.
Server.ColdFusion.ProductName | The name of the product (ColdFusion Server).
Server.ColdFusion.ProductVersion | The version number for the server that is running, such as 6,0,0.
Server.ColdFusion.Rootdir | Directory under which ColdFusion is installed, such as C:\cfusion.
Server.ColdFusion.SerialNumber | The serial number assigned to this server installation.
Server.ColdFusion.SupportedLocales | The locales, such as English (US) and Spanish (Standard), supported by the server.
Server.OS.AdditionalInformation | Additional information provided by the operating system, such as the Service Pack number.
Server.OS.arch | The processor architecture, such as x86 for Intel Pentium processors.
Server.OS.BuildNumber | The specific operating system build, such as 1381
Server.OS.Name | The name of the operating system, such as Windows NT.
Server.OS.Version | The version number of the operating system, such as 4.0.


Locking code with cflock

The cflock tag controls simultaneous access to ColdFusion code. The cflock tag lets you do the following:

  • Protect sections of code that access and manipulate shared data in the Session, Application, and Server scopes.
  • Ensure that file updates do not fail because files are open for writing by other applications or ColdFusion tags.
  • Ensure that applications do not try to simultaneously access ColdFusion extension tags written using the CFX API that are not thread-safe. This is particularly important for CFX tags that use shared (global) data structures without protecting them from simultaneous access (not thread-safe). However, Java CFX tags can also access shared resources that could become inconsistent if the CFX tag access is not locked.
  • Ensure that applications do not try to simultaneously access databases that are not thread-safe. (This is not necessary for most database systems.)

ColdFusion Server is a multithreaded web application server that can process multiple page requests at a time. As a result, the server can attempt to access the same information or resources simultaneously, as the result of two or more requests.

While the ColdFusion Server is thread-safe and does not try to modify a variable simultaneously, it does not ensure the correct order of access to information. If multiple pages, or multiple invocations of a page, attempt to write data simultaneously, or read and write it at the same time, the resulting data can be inconsistent, as illustrated in the following Sample locking scenariossection.

Similarly, the ColdFusion Server cannot automatically ensure that two sections of code do not attempt to access external resources such as files, databases, or CFX tags that cannot properly handle simultaneous requests. Nor can the ColdFusion Server ensure that the order of access to these shared resources is consistent and results in valid data.

By locking code that accesses such resources so that only one thread can access the resource at a time, you ensure data integrity.


Sample locking scenarios

The following examples present scenarios in which you need to lock ColdFusion code. These scenarios show only two of the circumstances where locking is vital.


Reading and writing a shared variable

If you have an application-wide value, such as a counter of the total number of tickets sold, you might have code such as the following on a login page:

<cfset Application.totalTicketsSold = Application.totalTicketsSold + ticketOrder>

When ColdFusion executes this code, it performs the following operations:

  1. Retrieves the current value of Application.totalTicketsSold from temporary storage.
  2. Increments this value.
  3. Stores the result back in the Application scope.

Suppose that ColdFusion processes two ticket orders at approximately the same time, and that the value of Application.totalTicketsSold is initially 160. The following sequence might happen:

  1. Order 1 reads the total tickets sold as 160.
  2. Order 2 reads the total tickets sold as 160.
  3. Order 1 adds an order of 5 tickets to 160 to get 165.
  4. Order 2 adds an order of 3 tickets to 160 to get 163.
  5. Order 1 saves the value 165 to Application.totalTicketsSold
  6. Order 2 saves the value 163 to Application.totalTicketsSold

The application now has an inaccurate count of the tickets sold, and is in danger of selling more tickets than the auditorium can hold.

To prevent this from happening, lock the code that increments the counter, as follows:

<cflock scope="Application" timeout="10" type="Exclusive">
   <cfset Application.totalTicketsSold = Application.totalTicketsSold +
ticketOrder>
</cflock>

The cflock tag ensures that while ColdFusion performs the processing in the tag body, no other threads can access the Application scope. As a result, the second transaction is not processed until the first one completes. The processing sequence looks something like the following:

  1. Order 1 reaches the lock tag, which gets an Application scope lock.
  2. Order 1 reads the total tickets sold as 160.
  3. Order 2 reaches the lock tag. Because there is an active Application scope lock, ColdFusion waits for the lock to free.
  4. Order 1 adds an order of 5 tickets to 160 to get 165.
  5. Order 1 saves the value 165 to Application.totalTicketsSold.
  6. Order 1 exits the lock tag. The Application scope lock is now free.
  7. Order 2 gets the Application scope lock and can begin processing.
  8. Order 2 reads the total tickets sold as 165.
  9. Order 2 adds an order of 3 tickets to 165 to get 168.
  10. Order 2 saves the value 168 to Application.totalTicketsSold.
  11. Order 2 exits the lock tag, which frees the Application scope lock. ColdFusion can process another order.

The resulting Application.totalTickesSold value is now correct.


Ensuring consistency of multiple variables

Often an application sets multiple shared scope variables at one time, such as a number of values submitted by a user on a form. If the user submits the form, clicks the back button, and then resubmits the form with different data, the application might end up with a mixture of data from the two submissions, in much the same manner as shown in the previous section.

For example, an application might store information about order items in a Session scope shopping cart. If the user submits an item selection page with data specifying sage green size 36 shorts, and then resubmits the item specifying sea blue size 34 shorts, the application might end up with a mixture of information from the two orders, such as sage green size 34 shorts.

By putting the code that sets all of the related Session variables in a single cflock tag, you ensure that all the variables get set together. In other words, setting all of the variables becomes an atomic, or single, operation. It is similar to a database transaction, where everything in the transaction happens, or nothing happens. In this example, the order details for the first order all get set, and then they are replaced with the details from the second order.

For more examples of using locking in applications, see Examples of cflock.


Using the cflock tag with write-once variables

You do not need to use cflock when you read a variable or call a user-defined function name in the Session, Application, or Server scope if it is set in only one place in the application, and is only read (or called, for a UDF) everywhere else. Such data is called write-once. If you set an Application or Session scope variable in Application.cfm and never set it on any other pages, you must lock the code that sets the variable, but do not have to lock code on other pages that reads the variable’s value.

However, although leaving code that uses write-once data unlocked can improve application performance, it also has risks. You must make sure that the variables are truly written only once. For example, you must make sure that the variable is not rewritten if the user refreshes the browser or clicks a back button. Also, it can be difficult to ensure that you, or future developers, do not later set the variable in more than one place in the application.


Using the cflock tag

The cflock tag ensures that concurrently executing requests do not run the same section of code simultaneously and thus manipulate shared data structures, files, or CFX tags inconsistently. It is important to remember that cflock protects code sections that access or set data, not the variables themselves.

You protect access to code by surrounding it in a cflock tag; for example:

<cflock scope="Application" timeout="10" type="Exclusive">
   <cfif not IsDefined("Application.number")>
      <cfset Application.number = 1>
   </cfif>
</cflock>


Lock types

The cflock tag offers two modes of locking, specified by the type attribute:

  • Exclusive locks (the default lock type) Allow only one request to process the locked code. No other requests can run code inside the tag while a request has an exclusive lock.

    • Enclose all code that creates or modifies Session, Application, or Server variables in exclusive cflock tags.

  • Read-only locks Allow multiple requests to execute concurrently if no exclusive locks with the same scope or name are executing. No requests can run code inside the tag while a request has an exclusive lock.

    • Enclose code that only reads or tests Session, Application, or Server variables in read-only cflock tags. You specify a read-only lock by setting the type="readOnly" attribute in the cflock tag, for example:

    <cflock scope="Application" timeout="10" type="readOnly">
   <cfif IsDefined("Application.dailyMessage")>
      <cfoutput>#Application.dailyMessage#<br></cfoutput>
   </cfif>
</cflock>

Although ColdFusion does not prevent you from setting shared variables inside read-only lock tag, doing so loses the advantages of locking. As a result, you must be careful not to set any Session, Application, or Server variables inside a read-only cflock tag body.


Lock scopes and names

The cflock tag prevents simultaneous access to sections of code, not to variables. If you have two sections of code that access the same variable, they must be synchronized to prevent them from running simultaneously. You do this by identifying the locks with the same scope or name attributes.

Note: ColdFusion does not require you to identify exclusive locks. If you omit the identifier, the lock is anonymous and you cannot synchronize the code in the cflock tag block with any other code. Anonymous locks do not cause errors when they protect a resource that is used in a single code block, but they are bad programming practice. You must always identify read-only locks.


Controlling access to data with the scope attribute

When the code that you are locking accesses Session, Application, or Server variables, synchronize access by using the cflock scope attribute.

You can set the attribute to any of the following values:

Scope | Meaning
Server | All code sections with this attribute on the server share a single lock.
Application | All code sections with this attribute in the same application share a single lock.
Session | All code sections with this attribute that run in the same session of an application share a single lock.

If multiple code sections share a lock, the following rules apply:

  • When code is running in a cflock tag block with the type attribute set to Exclusive, code in cflock tag blocks with the same scope attribute is not allowed to run. They wait until the code with the exclusive lock completes.
  • When code in a cflock tag block with the type readOnly is running, code in other cflock tag blocks with the same scope attribute and the readOnly type attribute can run, but any blocks with the same scope attribute and an Exclusive type cannot run and must wait until all code with the read-only lock completes. However, if a read-only lock is active and code with an exclusive lock with the same scope or name is waiting to execute, read-only requests using the same scope or name that are made after the exclusive request is queued must wait until code with the exclusive lock executes and completes.


Controlling locking access to files and CFX tags with the name attribute

The cflock name attribute provides a second way to identify locks. Use this attribute when you use locks to protect code that manges file access or calls non-thread-safe CFX code.

When you use the name attribute, specify the same name for each section of code that accesses a specific file or a specific CFX tag.


Controlling and minimizing lock time-outs

You must include a timeout attribute in your cflock tag. The timeout attribute specifies the maximum time, in seconds, to wait to obtain the lock if it is not available. By default, if the lock does not become available within the time-out period, ColdFusion generates a Lock type exception error, which you can handle using cftry and cfcatch tags.

If you set the cflock throwOnTimeout attribute to No, processing continues after the time-out at the line after the </cflock> end tag. Code in the cflock tag body does not run if the time-out occurs before ColdFusion can acquire the lock. Therefore, never use the throwOnTimeout attribute for CFML that must run.

Normally, it should not take more than a few seconds to obtain a lock. Very large time-outs can block request threads for long periods of time and radically decrease throughput. Always use the smallest time-out value that does not result in a significant number of time-outs.

To prevent unnecessary time-outs, lock the minimum amount of code possible. Whenever possible, lock only code that sets or reads variables, not business logic or database queries. One useful technique is to do the following:

  1. Perform a time-consuming activity outside of a cflock tag
  2. Assign the result to a Variables scope variable
  3. Assign the Variables scope variable’s value to a shared scope variable inside a cflock block.

For example, if you want to assign the results of a query to a Session variable, first get the query results using a Variables scope variable in unlocked code. Then, assign the query results to a Session variable inside a locked code section. The following code illustrates this technique:

<cfquery name="Variables.qUser" datasource="#request.dsn#">
   SELECT FirstName, LastName
   FROM Users
   WHERE UserID = #request.UserID#
</cfquery>
<cflock scope="Session" timeout="5" type="exclusive">
   <cfset Session.qUser = Variables.qUser>
</cflock>


Considering lock granularity

When you design your locking strategy, consider whether you should have multiple locks containing small amounts of code or few locks with larger blocks of code. There is no simple rule for making such a decision, and you may want to do performance testing with different options to help make your decision. However, you must consider the following issues:

  • If the code block is larger, ColdFusion will spend more time inside the block, which might increase the number of times an application waits for the lock to released.
  • Each lock requires processor time. The more locks you have, the more processor time is spent on locking code.


Nesting locks and avoiding deadlocks

Inconsistent nesting of cflock tags and inconsistent naming of locks can cause deadlocks (blocked code). If you are nesting locks, you must consistently nest cflock tags in the same order and use consistent lock scopes (or names).

A deadlock is a state in which no request can execute the locked section of the page. All requests to the protected section of the page are blocked until there is a time-out. The following table shows one scenario that would cause a deadlock:

User 1 | User 2
Locks the Session scope. | Locks the Application scope.
Tries to lock the Application scope, but the Application scope is already locked by User 2. | Tries to lock the Session scope, but the Session scope is already locked by User 1.

Neither user’s request can proceed, because it is waiting for the other to complete. The two are deadlocked.

Once a deadlock occurs, neither of the users can do anything to break the deadlock, because the execution of their requests is blocked until the deadlock is resolved by a lock time-out.

You can also cause deadlocks if you nest locks of different types. An example of this is nesting an exclusive lock inside a read-only lock of the same scope or same name.

In order to avoid a deadlock, lock code sections in a well-specified order, and name the locks consistently. In particular, if you need to lock access to the Server, Application, and Session scopes, you must do so in the following order.

  1. Lock the Session scope. In the cflock tag, specify scope="Session".
  2. Lock the Application scope. In the cflock tag, specify scope="Application".
  3. Lock the Server scope. In the cflock tag, specify scope="Server".
  4. Unlock the Server scope.
  5. Unlock the Application scope.
  6. Unlock the Session scope.

Note: You can skip any pair of lock and unlock steps in the preceding list if you do not need to lock a particular scope. For example, you can omit steps 3 and 4 if you do not need to lock the Server scope.


Copying shared variables into the Request scope

You can avoid locking some shared-scope variables multiple times during a request by doing the following:

  1. Copy the shared-scope variables into the Request scope in code with an exclusive lock the Application.cfm page.
  2. Use the Request scope variables on your ColdFusion pages for the duration of the request.
  3. Copy the variables back to the shared scope in code with an exclusive lock on the OnRequestEnd.cfm page.

With this technique the “last request wins.” For example, if two requests run simultaneously, and both requests change the values of data that was copied from the shared scope, the data from the last request to finish is saved in the shared scope, and the data from the previous request is not saved.


Locking Application variables efficiently

The need to lock Application variables can reduce server performance, because all requests that use Application scope variables must wait on a single lock. This issue is a problem even for write-once read-many variables, because you still must ensure the variable exists, and possibly set the value before you can read it.

You can minimize this problem by using a technique such as the following to test for the existence of Application variables and set them if they do not exist.

  1. Use an Application scope flag variable to indicate if the variable or variables are initialized. In a read-only lock, check for the existence of the flag, and assign the result to a local variable.
  2. Outside the cflock bock, test the value of the local variable
  3. If it the local variable indicates that the Application variables are not initialized, get an exclusive Application scope lock.
  4. Inside the lock, again test the Application scope flag, to make sure another page has not set the variables between step one and step four.
  5. If the variables are still not set, set them and set the Application scope flag to true.
  6. Release the exclusive lock.

The following code shows this technique:

<!--- Initilialize local flag to false --->
<cfset app_is_initialized = False>
<!--- Get a readonly lock --->
<cflock scope="application" type="readonly">
   <!--- read init flag and store it in local variable --->
   <cfset app_is_initialized = IsDefined("APPLICATION.initialized")>
</cflock>
<!--- Check the local flag --->
<cfif not app_is_initialized >
<!--- Not initialized yet, get exclusive lock to write scope --->
   <cflock scope="application" type="exclusive">
      <!--- Check nonlocal flag since multiple requests could get to the
            exclusive lock --->
      <cfif not IsDefined("APPLICATION.initialized") >
         <!--- Do initializations --->
         <cfset APPLICATION.varible1 = someValue >
          ...
         <!--- Set the Application scope initialization flag --->
         <cfset APPLICATION.initialized = "yes">
      </cfif>
   </cflock>
</cfif>


Examples of cflock

The following examples show how to use cflock blocks in a variety of situations.


Example with Application, Server, and Session variables

This example shows how you can use cflock to guarantee the consistency of data updates to variables in the Application, Server, and Session scopes.

This example does not handle exceptions that arise if a lock times out. As a result, users see the default exception error page on lock time-outs.

The following sample code might be part of the Application.cfm file:

<cfapplication name="ETurtle"
   sessiontimeout=#createtimespan(0,1,30,0)#
   sessionmanagement="yes">

<!--- Initialize the Session and Application
variables that will be used by E-Turtleneck. Use
the Session lock scope for the Session variables. --->

<cflock scope="Session"
   timeout="10" type ="Exclusive">
   <cfif not IsDefined("session.size")>
      <cfset session.size = "">
   </cfif>
   <cfif not IsDefined("session.color")>
      <cfset session.color = "">
   </cfif>
</cflock>

<!--- Use the Application scope lock for the Application.number variable.
This variable keeps track of the total number of turtlenecks sold.
The following code implements the scheme shown in the Locking Application
variables effectively section --->

<cfset app_is_initialized = "no">
<cflock scope="Application" type="readonly">
   <cfset app_is_initialized = IsDefined("Application.initialized")>
</cflock>
<cfif not app_is_initialized >
   <cflock scope="application" timeout="10" type="exclusive">
      <cfif not IsDefined("Application.initialized") >
         <cfset Application.number = 1>
         <cfset Application.initialized = "yes">
      </cfif>
   </cflock>
</cfif>

<!--- Always display the number of turtlenecks sold --->

<cflock scope="Application"
   timeout="10"
   type ="ReadOnly">
   <cfoutput>
   E-Turtleneck is proud to say that we have sold
   #Application.number# turtlenecks to date.
   </cfoutput>
</cflock>

The remaining sample code could appear inside the application page where customers place orders:

<html>
<head>
<title>cflock Example</title>
</head>

<body>
<h3>cflock Example</h3>

<cfif IsDefined("Form.submit")>

<!--- Lock Session variables --->
<!--- Note that we use the automatically generated Session
   ID as the order ID --->
<cflock scope="Session"
   timeout="10" type="ReadOnly">
   <cfoutput>Thank you for shopping E-Turtleneck.
   Today you have chosen a turtleneck in size
   <b>#form.size#</b> and in the color <b>#form.color#</b>.
   Your order ID is #Session.sessionID#.
   </cfoutput>
</cflock>

<!--- Lock Session variables to assign form values to them. --->

<cflock scope="Session"
   timeout="10"
   type="Exclusive">
   <cfparam name=Session.size default=#form.size#>
   <cfparam name=Session.color default=#form.color#>
</cflock>
<
!--- Lock the Application scope variable application.number to
update the total number of turtlenecks sold. --->

<cflock scope="Application"
   timeout="30" type="Exclusive">
   <cfset application.number=application.number + 1>
</cflock>

<!--- Show the form only if it has not been submitted. --->
<cfelse>
<form action="cflock.cfm" method="Post">

<p> Congratulations! You have just selected
the longest-wearing, most comfortable turtleneck
in the world. Please indicate the color and size
you want to buy.</p>

<table cellspacing="2" cellpadding="2" border="0">
<tr>
<td>Select a color.</td>
<td><select type="Text" name="color">
      <option>red
      <option>white
      <option>blue
      <option>turquoise
      <option>black
      <option>forest green
      </select>
   </td>
</tr>
<tr>
   <td>Select a size.</td>
   <td><select type="Text" name="size">
      <option>small
      <option>medium
      <option>large
      <option>xlarge
      </select>
   </td>
</tr>
<tr>
   <td></td>
   <td><input type="Submit" name="submit" value="Submit">
   </td>
</tr>
</table>
</form>
</cfif>

</body>
</html>

Note: In this simple example, the Application.cfm page displays the Application.number variable value. Because the Application.cfm file is processed before any code on each CFML page, the number that displays after you click the submit button does not include the new order. One way you can resolve this problem is by using the OnRequestEnd.cfm page to display the value at the bottom of each page in the application.


Example of synchronizing access to a file system

The following example shows how to use a cflock block to synchronize access to a file system. The cflock tag protects a cffile tag from attempting to append data to a file already open for writing by the same tag executing on another request.

If an append operation takes more than 30 seconds, a request waiting to obtain an exclusive lock to this code might time out. Also, this example uses a dynamic value for the name attribute so that a different lock controls access to each file. As a result, locking access to one file does not delay access to any other file.

<cflock name=#filename# timeout=30 type="Exclusive">
   <cffile action="Append"
      file=#fileName#
      output=#textToAppend#>
</cflock>


Example of protecting ColdFusion extensions

The following example shows how you can build a custom tag wrapper around a CFX tag that is not thread-safe. The wrapper forwards attributes to the non-thread-safe CFX tag that is used inside a cflock tag.

<cfparam name="Attributes.AttributeOne" default="">
<cfparam name="Attributes.AttributeTwo" default="">
<cfparam name="Attributes.AttributeThree" default="">

<cflock timeout=5
      type="Exclusive"
      name="cfx_not_thread_safe">
   <cfx_not_thread_safe attributeone=#attributes.attributeone#
      attributetwo=#attributes.attributetwo#
      attributethree=#attributes.attributethree#>
</cflock>
Previous


Securing Applications

ColdFusion has two major security features: resource (file and directory-based) security and user (programmatic) security. This chapter provides an overview of ColdFusion security. It briefly describes how you use the Administrator to configure resource security, and discusses structuring an application to take advantage of resource security. It explains in detail how to implement user security in ColdFusion applications.

Other chapters discuss specific security issues as part of the context of their topics. For example, the chapter on LDAP discusses secure access to LDAP directories. Similarly, the section Enhancing security with cfqueryparam describes a method for preventing inappropriate access to SQL databases. See the Security entries in the Index for a complete listing of such sections.

For detailed information on using Administrator-controlled security features, see Administering ColdFusion MX.

This chapter does not discuss general or web server security concepts and issues. For example, it does not discuss web server security management issues, such as enabling HTTPS protocol support. For information on enabling web server security features, see your web server documentation. Many books and other resources are available on web and application security.

Contents
  • ColdFusion security features
  • About resource security
  • About user security
  • Implementing user security
Next


ColdFusion security features

ColdFusion provides scalable, granular security for building and deploying your ColdFusion applications. ColdFusion provides following types of security resources:

  • Development ColdFusion Administrator is protected by a password. Additionally, you can specify a password for access to data sources from Macromedia Dreamweaver MX. For more information on configuring Administrator security passwords, see ColdFusion Administrator online Help. This chapter does not these passwords. For more information see the Administrator Help.
  • Resource The ColdFusion Administrator can limit access to ColdFusion resources, including selected tags and functions, data sources, files, and host addresses, based on the location of your CFML pages. You can confine applications to secure areas, thereby flexibly restricting the access that the application has to resources.
  • User ColdFusion Applications can require users to log in to use application pages. You can assign users to roles (sometimes called groups); ColdFusion pages can determine the logged-in user’s role or ID and selectively determine what to do based on this information.

Note: You can also use the cfencode utility, located in the cf_root/bin directory, to obfuscate CFML pages that you distribute. Although this technique cannot prevent determined hackers from determining the contents of your pages, it does prevent inspection of the pages.


About resource security

Resource security lets you secure access to ColdFusion resources based on the ColdFusion page location, by applying a set of access rules to all ColdFusion pages in a directory. The directory or directories to which a set of rules apply is called a sandbox, and resource security is also called sandbox security. The ColdFusion Administrator Security Settings page enables resource security; the Sandbox Security page configures access to resources. Resource security controls access to the following resources:

Resource
Description
Data Sources
Enables access to specified data sources.
CF Tags
Prevents pages from using CFML tags that access external resources. You can prevent pages in the directory from using any or all of the following tags:
cfcollection, cfcontent, cfcookie, cfdirectory, cfexecute, cffile, cfftp, cfgridupdate, cfhttp, cfhttpparam, cfindex, cfinsert, cfinvoke, cfldap, cflog, cfmail, cfobject, cfobjectcache, cfquery, cfregistry, cfschedule, cfsearch, cfstoredproc, cftransaction, cfupdate
CF Functions
Prevents pages from using CFML functions that access external resources. You can prevent pages from using any or all of the following functions:
CreateObject, DirectoryExists. ExpandPath, FileExists, GetBaseTemplatePath, GetDirectoryFromPath, GetFileFromPath, GetProfileString, GetTempDirectory, GetTemplatePath, SetProfileString
Files/Directories
Sets read, write, execute, and delete access to specified directories, directory trees, or files.
Server/Ports
Controls access to IP addresses and port numbers. You can specify host names or numeric addresses, and you can specify individual ports and port ranges.

By default, resource security rules apply to the specified directory and all its subdirectories. If you create a set of rules for a subdirectory of another sandbox, the subdirectory’s rules override the parent directory’s rules.

Resource security lets you apply different sets of rules to different directory structures. You can use it to partition a shared hosting environment, so that a number of applications with different purposes, and possibly different owners, run securely on a single server. When multiple applications share a host, you set up a separate directory structure for each application, and apply rules that allow each application to access only its own data sources and files.

Resource security also lets you to structure and partition an application to reflect the access rights that are appropriate to different functional components. For example, if your application has both user functions and administrator functions, you could structure the application as follows:

  • Administrator pages go in one directory with access rules that enable most activities.
  • User pages go in another directory whose rules limit the files they can modify and the tags they can use.
  • Pages required for both administrative and user functions go in a third directory with appropriate access rules.

For more information on configuring resource security, see Administering ColdFusion MX.


About user security

User security lets your application use security rules to determine what it displays. It has two elements:

  • Authentication
  • Authorization

Authentication ensures that a valid user is logged in, based on an ID and password provided by the user. ColdFusion maintains the user ID information while the user is logged in.

Authorization ensures that the logged-in user is allowed to use a page or perform an operation. Authorization is typically based on one or more roles (sometimes called groups) to which the user belongs. For example, in an employee database, all users could be members of either the employee role or the contractor role. They could also be members of roles that identify their department, position in the corporate hierarchy, or job description. For example, someone could be a member of some or all of the following roles:

  • Employees
  • Human Resources
  • Benefits
  • Managers

Roles enable you to control access in your application resources without requiring the application to maintain knowledge about individual users. For example, suppose you use ColdFusion for your company’s intranet. The Human Resources department maintains a page on the intranet on which all employees can access timely information about the company, such as the latest company policies, upcoming events, and job postings. You want everyone to be able to read the information, but you want only certain authorized Human Resources employees to be able to add, update, or delete information.

Your application gets the user’s roles from the user information data store at log in, and then enables access to specific pages or features based on the roles. Typically, you store user information in a database, LDAP directory, or other secure information store.

You can also use the user ID for authorization. For example, you might want to let employees view customized information about their salaries, job levels, and performance reviews. You certainly would not want one employee to view sensitive information about another employee, but you would want managers to be able to see, and possibly update, information about their direct reports. By employing both user IDs and roles, you can ensure that only the appropriate people can access or work with sensitive data.

The following diagram shows a typical flow of control for user authentication and authorization. Following sections expand on this diagram to show how you implement user security in ColdFusion.

This is a picture of the feature being described.


Security tags and functions

ColdFusion provides the following tags and functions for user security

Tag or function
Purpose
cflogin
A container for user authentication and login code. The body of the tag runs only if there is no logged-in user. When using application-based security, you put code in the body of the cflogin to check the user-provided ID and password against a data source, LDAP directory, or other repository of login identification. The body includes a cfloginuser tag (or a ColdFusion page that contains a cfloginuser tag) to establish the authenticated user’s identity in ColdFusion.
cfloginuser
Identifies the authenticated user to ColdFusion. Specifies the user’s ID, password, and roles. Typically used inside cflogin tags.
The cfloginuser tag requires three attributes, name, password, and roles, and does not have a body. The roles attribute is a comma- delimited list of role identifiers to which the logged-in user belongs. All spaces in the list are treated as part of the role names, so you should not follow commas with spaces.
cflogout
Logs out the current user. Removes knowledge of the user ID and roles from the server. If you do not use this tag, the user is automatically logged out when the session ends.
The cflogout tag does not take any attributes, and does not have a body.
cffunction
Used only in cfcomponent tags. If you include a roles attribute, the function executes only when there is a logged in user who belongs to one of the specified roles.
IsUserInRole
Returns True if the current user is a member of the specified role.
GetAuthUser
Returns the ID of the current logged in user.


About web server authentication and application authentication

ColdFusion supports two forms of user authentication:

  • Web server basic authentication
  • Application authentication


About Web server basic authentication

All major web servers support basic authentication, also known as basic HTTP authentication. The web server requires the user to log in to access pages in a particular directory, as follows:

  1. When the user first request a page in the secured directory, the web server presents the user with a login page
  2. The user fills in the login page and submits it
  3. The web server checks the user’s login ID and password using its own user authentication mechanism.
  4. If the user logs in successfully, the browser caches the authentication information and sends it with every subsequent page request from the user.
  5. The web server processes the requested page and all future page requests from the browser that contain the cached login information, if it is valid for the requested page.

The application can perform additional authorization checks based on the information provided by the browser with each request. For example, the application can determine the user’s roles based on the login ID and check the roles against specific roles required to access pages or sections of code within pages.

You can use basic web server authentication without using any ColdFusion security features. In this case, you only perform directory-based user authentication, and you configure all user security through the web server’s interfaces. You do not use any of the ColdFusion security features, and typically do not perform role-based authorization.

You can also use basic web server authentication with ColdFusion security tags and functions to enforce user authorization. In this case you rely on the web server for user authentication, and your application does not have to display a login page. You then use the web server authentication information with the cflogin and cfloginuser tags to log the user into the ColdFusion user security system and use the IsUserInRole and GetUserName functions to ensure user authorization. For more information on this form of security see A basic authentication security scenario.


About application authentication

With application authentication, you do not rely on the web server to enforce application security. The application performs all user authentication and authorization. The application displays a login page, checks the user’s identity and login against its own authorization store, such as an LDAP directory or database, and logs the user into ColdFusion using the cfloginuser tag. The application can then use the IsUserInRole and GetUserName functions to check the user’s roles or identity before running a ColdFusion page or specific code on a page. For more information on application authentication, see An application authentication security scenario.


Controlling ColdFusion login behavior

When you use the cfloginuser tag within a cflogin tag, ColdFusion stores a login token in a memory-only browser cookie. Therefore, to use the cflogin tag to check for an authenticated user, the user must enable memory-only cookies in the browser. The login cookie does not lasts after the user closes the browser.

You can use the cfloginuser tag without user cookies, but the login information remains in effect for only the current page. For more information on user logins without cookies, see Using ColdFusion security without cookies.

The cflogin tag has three optional arguments that control the characteristics of a ColdFusion login, as follows:

Attribute | Use
idleTimeout | If no page requests occur during the idleTiemout period, the ColdFusion logs the user out. The default is 1800 seconds (30 minutes).
applicationToken | Limits the login validity to a specific application as specified by a ColdFusion page’s cfapplication tag. The default value is the current application name.
cookieDomain | The Internet domain for which the ColdFusion security cookie is valid. By default, there are no domain limitations.


Logging a user out

After a user logs in, the ColdFusion user authorization and authentication information remains valid until any of the following happens:

  • The login times out. This happens if the user does not request a new page for the idleTimeout period.
  • The application uses a cflogout tag to log out the user, usually in response to the user clicking a logout link or button.
  • The user closes the browser.


Specifying an applicationToken value

The login identification created by cflogin tag is valid only for pages within the directory that contains the cflogin tag and any of its subdirectories. Therefore, if a user requests a page in another directory tree, the current login credentials are not valid for accessing those pages. This security limitation lets you use the same user names and passwords for different sections of your application (for example, a UserFunctions tree and a SecurityFunctions tree) and enforce different roles to the users depending on the section.

ColdFusion uses the applicationToken value to generate a unique identifier that enforces this rule. The default applicationToken value is the current application name, as specified by a cfapplication tag. In normal usage, there you do not need to specify a applicationToken value in the cflogin tag.


Limiting the valid internet domain

Use the cookieDomain attribute to limit the log-in capabilities to users from a specific domain or even a specific system. For example, to ensure that only users located in the macromedia.com domain can log in to your application, specify cookieDomain=".macromedia.com". To specify a domain name, you start the name with a period.


The cflogin structure

The cflogin tag has a built-in cflogin structure that contains two variables: cflogin.name and cflogin.password. These variables contain the user ID and password in either of the following cases:

  • The cflogin tag body is executing in response to a user logging in on the browser’s basic login page.
  • The cflogin tag body is executing in response to a user logging in on an application login form that contains input fields with the names j_username and j_password.

Therefore, the cflogin structure provides a consistent interface for determining the user’s login ID and password independent of the technique you use for displaying the login form.


Using ColdFusion security without cookies

You can implement a limited-lifetime form of ColdFusion security if the user’s browser does not support cookies. In this case you do not use the cflogin tag, only the cfloginuser tag. It is the only time you should use the cfloginuser tag outside a cflogin tag.

Without browser cookies, the effect of the cfloginuser tag is limited to a single HTTP request. You must provide your own authentication mechanism and call cfloginuser on each page where you use ColdFusion login identification.


A basic authentication security scenario

An application that uses basic web server authentication might work as follows. The example in Basic authentication user security example implements this scenario.

  1. When the user requests a page from a particular directory on the server for the first time after starting the browser, the web server displays a login page and logs the user in. The web server handles all user authentication.
  2. Because the user requested a ColdFusion page, the web server hands the request to ColdFusion
  3. When ColdFusion receives a request for a CFML page, it runs the contents of the Application.cfm page before it runs the requested page. The Application.cfm page contains a cflogin tag. ColdFusion executes the cflogin tag body if the user is not logged into ColdFusion. The user is logged in if the cfloginuser tag has run successfully for this application and the user has not been logged out by a cflogout tag or the login has not timed out from inactivity.
  4. Code in the cflogin tag body uses the user ID and password from browser login, contained in the cflogin.name and cflogin.password variables, as follows:
    1. First it checks the user’s name against information it maintains about users and roles. In a simple case, the application might have two roles, one for users and one for administrators. The CFML assigns the Admin role to any user logged on with the user ID "Admin" and assigns the User role to all other users.
    2. The cflogin tag body code calls the cfloginuser tag with the user’s ID, password, and roles to identify the user to ColdFusion.
  5. Application.cfm completes processing and ColdFusion processes the requested application page.
  6. The application pages use the IsUserInRole function to check whether the user belongs to a role before they run protected code that must be available only to users in that role. For example, administrative pages

    7. The application can use the GetAuthUser function to determine the user ID; for example, to display the ID for personalization. It can also use the ID as a database key to get user-specific data.


An application authentication security scenario

An application that does its own authentication might work as follows. The example in Application-based user security example implements this scenario.

  1. Whenever ColdFusion receives a request for a CFML page, it runs the contents of the Application.cfm page before it runs the requested page. The Application.cfm page contains a cflogin tag. ColdFusion executes the cflogin tag body if the user is not logged in. A user is logged in if the cfloginuser tag has run during the current session and the user had not been logged out by a cflogout tag.
  2. Code in the cflogin tag body checks to see if it has received a user ID and password, normally from a login form.
  3. If there is no user ID or password, the code in cflogin tag body displays a login form that asks for the user’s ID and password.

    4. The form posts the login information back to the originally-requested page, and the login tag in Application.cfm runs again. This time, the cflogin tag body code checks the user name and password against a database, LDAP directory, or other policy store to ensure that the user is valid and get the user’s roles.

  4. If the user name and password are valid, the cflogin tag body code calls the cfloginuser tag with the user’s ID and roles to identify the user to ColdFusion.
  5. When the user is logged in, application pages use the IsUserInRole function to check whether the user belongs to a role before they run protected code that must be available only to users in that role.

    6. The application can use the GetAuthUser function to determine the user ID; for example, to display the ID for personalization. It can also use the ID as a database key to get user-specific data.

  6. Each application page displays a link to a log-out form that uses the cflogout tag to log out the user. Typically, the logout link is in a page header that appears in all pages. The logout form can also be on the Application.cfm page.

Note: A log-out option is not always required, as the user is automatically logged out when the browser closes or is inactive for the time-out period. However, you can enhance security in cases where a system may be shared by providing a log-out facility. You must explicitly log out a user before a new user can log in using the same browser session.

While this scenario shows one method for implementing user security, it is only an example. For example, your application could require users to log in for only some pages, such a pages in folder containing administrative functions. When you design your user security implementation, remember the following:

  • Code in the cflogin tag body executes only if there is no user logged in.
  • You must write the code that gets the identification from the user and tests this information against the a secure credential store.
  • After you have authenticated the user, you use the cfloginuser to log the user into the ColdFusion session.

The following diagram shows this flow of control. For simplicity, it omits the logout button.

This is a picture of the feature being described.


Implementing user security

The following section provide several examples of ways to implement security using basic authentication and application authentication


Basic authentication user security example

The example in this section shows how you might implement user security using web-server basic authentication and two roles, user and administrator.

This example has two ColdFusion pages:

  • The Application.cfm page logs the user into the ColdFusion security system and assigns the user to specific roles based on the user’s ID.

    • This page also includes the one-button form and logic for logging out a user, which appears at the top of each page.

  • The securitytest.cfm page is a sample application page. It displays the logged-in user’s roles.

You can test the security behavior by adding your own pages to the same directory as the Application.cfm page.


Example: Application.cfm

The Application.cfm page consists of the following:

<cfapplication name="Orders">
<cflogin>
   <cfif IsDefined( "cflogin" )>
      <cfif cflogin.name eq "admin">
         <cfset roles = "user,admin">
      <cfelse>
            <cfset roles = "user">
         </cfif>
      <cfloginuser name = "#cflogin.name#" password = "#cflogin.password#"
         roles = "#roles#" />
   <cfelse>
      <!--- this should never happen --->
      <h4>Authentication data is missing.</h4>
         Try to reload the page or contact the site administrator.
   <cfabort>
   </cfif>
</cflogin>


Reviewing the code

The Application.cfm page executes before the code in each ColdFusion page in an application. For more information on the Application.cfm page and when it is executed, see Designing and Optimizing a ColdFusion Application. The following table describes the CFML code in Application.cfm and its function:.

Code
Description
<cfapplication name="Orders"
Identifies the application. The login information on this page only applies to this application.
<cflogin>
   <cfif IsDefined( "cflogin" )>
      <cfif cflogin.name eq "admin">
         <cfset roles = "user,admin">
      <cfelse>
            <cfset roles = "user">
         </cfif>
Executes if there is no logged-in user.
Makes sure the user is correctly logged in by the web-server. (Otherwise there would be no cflogin variable.)
Sets a roles variable based on the user’s ID. assigns users named "admin" to the admin role. Assigns all other users to the users role.
<cfloginuser name = "#cflogin.name#"
   password = "#cflogin.password#"
   roles = "#roles#" />
Logs the user into the ColdFusion security system and specifies the user’s password, name and roles. Gets the password and name directly from the cflogin structure.
<cfelse>
   <!--- this should never happen --->
   <h4>Authentication data is missing.</h4>
      Try to reload the page or contact the
         site administrator.
   <cfabort>
This code should never run, but if the user somehow got to this page without logging in to the web server, this message would display and ColdFusion would stop processing the request.
   </cfif>
</cflogin>
Ends if/else block.
Ends the cflogin tag body.


Example: securitytest.cfm

The securitytest.cfm page shows how any application page can use ColdFusion user authorization features. The web server ensures the existence of an authenticated user, and the Application.cfm page ensures that the user is assigned to roles the page content appears. The securitytest.cfm page uses the IsUserInRole and GetAuthUser functions to control the information that is displayed.

The securitytest.cfm page consists of the following code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
   <title>Basic authentication security test page</title>
</head>

<body>
<cfoutput>
   <h2>Welcome #GetAuthUser()#!</h2>
</cfoutput>

ALL Logged-in Users see this message.<br>
<br>
<cfscript>
   if (IsUserInRole("admin"))
      WriteOutput("users in the admin role see this message.<br><br>");
   if (IsUserInRole("user"))
      WriteOutput("Everyone in the user role sees this message.<br><br>");
</cfscript>

</body>
</html>


Reviewing the code

The following table describes the securitytest.cfm page CFML code and its function.

Code
Description
<cfoutput>
<h2>Welcome #GetAuthUser()#!</h2>
</cfoutput>
Displays a welcome message that includes the user’s login ID.
ALL Logged-in Users see this    message.<br>
<br>
Displays this message in all cases. The page does not display until a user is logged in.
<cfscript>
   if (IsUserInRole("admin"))
      WriteOutput("users in the admin role
         see this message.<br><br>");
   if (IsUserInRole("user"))
      WriteOutput("Everyone in the user role
         sees this message.<br><br>");
</cfscript>
Tests whether the user belongs to each of the valid roles. If the user is in a role, displays a message with the role name.
The user sees one message per role to which he or she belongs.


Application-based user security example

The example in this section shows how you might implement user security by authenticating users and then allowing users to see or use only the resources that they are authorized to access.

This example has three ColdFusion pages:

  • The Application.cfm page contains the authentication logic that checks whether a user is logged in, requests the login page if the user is not logged in, and authenticates the data from the login page. If the user is authenticated, it logs the user in.

    • This page also includes the one-button form and logic for logging out a user, which appears at the top of each page.

  • The loginform.cfm page displays the login form. The code on this page could also be included in Application.cfm.
  • The securitytest.cfm page is a sample application page. It displays the logged-in user’s roles.

You can test the security behavior by adding your own pages to the same directory as the Application.cfm page.

The example gets user information from the LoginInfo table of the CompanyInfo database that is installed with ColdFusion. You can replace this database with any database containing UserID, Password, and Roles fields. The sample database contains the following data:

UserID | Password | Roles
BobZ | Ads10 | Employee,Sales
JaniceF | Qwer12 | Contractor,Documentation
RandalQ | ImMe | Employee,Human Resources,Manager

Note that because spaces are meaningful in roles strings, you should not follow the comma separators in the Roles fields with spaces.

The following sections contain listings and descriptions of each of the pages.


Example: Application.cfm

The Application.cfm page consists of the following:

<cfapplication name="Orders" sessionmanagement="Yes">

<cfif IsDefined("Form.logout")>
   <cflogout>
</cfif>

<cflogin>
   <cfif NOT IsDefined("cflogin")>
      <cfinclude template="loginform.cfm">
      <cfabort>
   <cfelse>
      <cfif cflogin.name IS "" OR cflogin.password IS "">
         <cfoutput>
            <H2>You must enter text in both the User Name and Password fields</H2>
         </cfoutput>
         <cfinclude template="loginform.cfm">
         <cfabort>
      <cfelse>
         <cfquery name="loginQuery" dataSource="CompanyInfo">
         SELECT UserID, Roles
         FROM LoginInfo
         WHERE
            UserID = '#cflogin.name#'
            AND Password = '#cflogin.password#'
         </cfquery>
         <cfif loginQuery.Roles NEQ "">
            <cfloginuser name="#cflogin.name#" Password = "#cflogin.password#"
               roles="#loginQuery.Roles#">
         <cfelse>
            <cfoutput>
               <H2>Your login information is not valid.<br>
               Please Try again</H2>
            </cfoutput>
            <cfinclude template="loginform.cfm">
            <cfabort>
         </cfif>
      </cfif>
   </cfif>
</cflogin>

<cfif GetAuthUser() NEQ "">
   <cfoutput>
       <form action="MyApp/index.cfm" method="Post">
         <input type="submit" Name="Logout" value="Logout">
      </form>
   </cfoutput>
</cfif>


Reviewing the code

The Application.cfm page executes before the code in each ColdFusion page in an application. For more information on the Application.cfm page and when it is executed, see Designing and Optimizing a ColdFusion Application. The following table describes the CFML code in Application.cfm and its function:.

Code
Description
<cfapplication name="Orders"
   sessionmanagement="Yes">
Identifies the application and enables Session scope variables.
<cfif IsDefined("Form.logout")>
   <cflogout>
</cfif>
If the user just submitted the logout form, logs out the user. Note that the following cflogin tag runs as a result.
<cflogin>
   <cfif NOT IsDefined("cflogin")>
      <cfinclude template="loginform.cfm">
      <cfabort>
Executes if there is no logged-in user.
Tests to see if the user has submitted a login form. If not, uses cfinclude to display the form. Uses the built-in cflogin variable that contains the user name and password if it was submitted by the login form.
The cfabort tag prevents processing of any code that follows on this page.
<cfelse>
   <cfif cflogin.name IS "" OR
      cflogin.password IS "">
      <cfoutput>
        <H2>You must enter text in both the
        User Name and Password fields</H2>
      </cfoutput>
      <cfinclude template="loginform.cfm">
      <cfabort>
Executes if the user submitted a login form.
Tests to make sure both name and password have data. If either variable is empty, displays a message, followed by the login form.
The cfabort tag prevents processing of any code that follows on this page.
<cfelse>
   <cfquery name="loginQuery"
         dataSource="CompanyInfo">
      SELECT UserID, Roles
      FROM LoginInfo
      WHERE
         UserID = '#cflogin.name#'
         AND Password = '#cflogin.password#'
   </cfquery>
Executes if the user submitted a login form and both fields contain data.
Uses the cflogin structure’s name and password entries to find the user record in the database and get the user’s roles.
<cfif loginQuery.Roles NEQ "">
   <cfloginuser name="#cflogin.name#"
      Password = "#cflogin.password#"
      roles="#loginQuery.Roles#">
If the query returns data in the Roles field, logs in the user using the UserID and Roles fields from the database. In this application, every user must be in some role.
<cfelse>
   <cfoutput>
      <H2>Your login information is not
         valid.<br>
      Please Try again</H2>
   </cfoutput>
   <cfinclude template="loginform.cfm">
   <cfabort>
Executes if the query did not return a role. If the database is valid, this means there was no entry matching the user ID and password. Displays a message, followed by the login form.
The cfabort tag prevents processing of any code that follows on this page.
         </cfif>
      </cfif>
   </cfif>
</cflogin>
Ends loginquery.Roles test code.
Ends form entry empty value test.
Ends form entry existence test.
Ends cflogin tag body.
<cfif GetAuthUser() NEQ "">
   <cfoutput>
      <form action="MyApp/index.cfm"
            method="Post">
         <input type="submit" Name="Logout"
            value="Logout">
      </form>
   </cfoutput>
</cfif>
If a user is logged in, displays the Logout button.
If the user clicks the button, posts the form to the application’s (theoretical) entry page, index.cfm.
Application.cfm then logs out the user and displays the login form. If the user logs in again, ColdFusion displays index.cfm.


Example: loginform.cfm

The loginform.cfm page consists of the following:

<cfset url="http://" & "#CGI.server_name#" & ":" &"#CGI.server_port#" &
    "#CGI.script_name#">
<cfif CGI.query_string IS NOT "">
   <cfset url=url & "?#CGI.query_string#">
</cfif>
<H2>Please Log In</H2>
<cfoutput>
   <form action="#url#" method="Post">
      <table>
         <tr>
            <td>username:</td>
            <td><input type="text" name="j_username"></td>
         </tr>
         <tr>
            <td>password:</td>
            <td><input type="password" name="j_password"></td>
         </tr>
      </table>
      <br>
      <input type="submit" value="Log In">
   </form>
</cfoutput>


Reviewing the code

The following table describes the loginform.cfm page CFML code and its function

Code
Description
<cfset url="http://" &
   "#CGI.server_name#" & ":" &
   "#CGI.server_port#" &
   "#CGI.script_name#">
<cfif CGI.query_string IS NOT "">
   <cfset url=url &
      "?#CGI.query_string#">
</cfif>
Constructs the URL to use in the form’s action attribute from CGI variables. The CGI.script_name variable identifies the originally requested page, because that page’s invocation of Application.cfm causes the login form to be displayed.
Appends any URL query string used in requesting the page so the page can process the request.
A more secure application would use the HTTPS protocol to encrypt the user name and password. To use HTTPS, you must obtain a security certificate and enable the protocol in your web server.
<H2>Please Log In</H2>
<cfoutput>
   <form action="#url#" method="Post">
      <table>
         <tr>
            <td>username:</td>
            <td><input type="text"
               name="j_username"></td>
         </tr>
         <tr>
            <td>password:</td>
            <td><input type="password"
               name="j_password"></td>
         </tr>
      </table>
      <br>
      <input type="submit" value="Login">
   </form>
</cfoutput>
Displays the login form. The form requests a user ID and password and posts the user’s input to the page specified by the url variable.
Uses the field names j_username and j_password. ColdFusion automatically puts form fields with these values in the cflogin.name and cflogin.password variables inside the cflogin tag


Example: securitytest.cfm

The securitytest.cfm page shows how any application page can use ColdFusion user authorization features. Application.cfm ensures the existence of an authenticated user before the page content appears. The securitytest.cfm page uses the IsUserInRole and GetAuthUser functions to control the information that is displayed.

The securitytest.cfm page consists of the following code:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
   <title>Security test page</title>
</head>

<body>
<cfoutput>
   <h2>Welcome #GetAuthUser()#!</h2>
</cfoutput>

ALL Logged-in Users see this message.<br>
<br>
<cfscript>
   if (IsUserInRole("Human Resources"))
      WriteOutput("Human Resources members see this message.<br><br>");
   if (IsUserInRole("Documentation"))
      WriteOutput("Documentation members see this message.<br><br>");
   if (IsUserInRole("Sales"))
      WriteOutput("Sales members see this message.<br><br>");
   if (IsUserInRole("Manager"))
      WriteOutput("Managers see this message.<br><br>");
   if (IsUserInRole("Employee"))
      WriteOutput("Employees see this message.<br><br>");
   if (IsUserInRole("Contractor"))
      WriteOutput("Contractors see this message.<br><br>");
</cfscript>

</body>
</html>


Reviewing the code

The following table describes the securitytest.cfm page CFML code and its function.

Code
Description
<cfoutput>
<h2>Welcome #GetAuthUser()#!</h2>
</cfoutput>
Displays a welcome message that includes the user’s login ID.
ALL Logged-in Users see this    message.<br>
<br>
Displays this message in all cases. The page does not display until a user is logged in.
<cfscript>
   if (IsUserInRole("Human Resources"))
      WriteOutput("Human Resources members
      see this message.<br><br>");
   if (IsUserInRole("Documentation"))
      WriteOutput("Documentation members see
      this message.<br><br>");
   if (IsUserInRole("Sales"))
      WriteOutput("Sales members see this
      message.<br><br>");
   if (IsUserInRole("Manager"))
      WriteOutput("Managers see this
      message.<br><br>");
   if (IsUserInRole("Employee"))
      WriteOutput("Employees see this
      message.<br><br>");
   if (IsUserInRole("Contractor"))
      WriteOutput("Contractors see this
      message.<br><br>");
</cfscript>
Tests whether the user belongs to each of the valid roles. If the user is in a role, displays a message with the role name.
The user sees one message per role to which he or she belongs.


Using application-based security with a browser’s login dialog

You do not have to create a login page to display a user login form; you can rely on the browser to display its standard login page. To do so, your cflogin tag body returns an HTTP status 401 to the browser if the user is not logged in or if the login fails. The browser then displays its login page and returns the information to the cflogin tag’s cflogin structure when the user clicks the login button.

For example, the following code tells the browser to display a login form if the user has not logged in, or if the user does not provide a name “user” and password “p1”, or a name “admin” and password “p2”:

<cflogin>
   <cfif IsDefined( "cflogin" )>
      <cfif cflogin.name eq "admin" and cflogin.password eq "p1">
         <cfset roles = "user,admin">
      <cfelseif cflogin.name eq "user" and cflogin.password eq "p2">
         <cfset roles = "user">
      </cfif>
   </cfif>

   <cfif IsDefined( "roles" )>
      <cfloginuser name="#cflogin.name#" password="#cflogin.password#"
roles="#roles#">
   <cfelse>
      <!--- User has not logged in or authentication failed - send 401 --->
      <cfsetting enablecfoutputonly="yes" showdebugoutput="no">
      <cfheader statuscode="401">
      <cfheader name="WWW-Authenticate" value="Basic realm=""MySecurity""">
      <cfoutput>Not authorized</cfoutput>
      <cfabort>

   </cfif>
</cflogin>


Using an LDAP Directory for security information

LDAP directories are often used to store security information. The following example cflogin tag checks an LDAP directory to authenticate the user and retrieve the users roles.

The most important thing to note in this example is that it queries the directory twice, first as the directory manager, then with the user’s identity:

  • The first query uses the identity of the directory manager as the username attribute. This query gets the distinguished name that corresponds to the user-supplied user ID. Using the directory manager’s identity ensures that there will be a valid response for any user ID in the directory.
  • The second query accesses the directory with the distinguished name from the first query as the username attribute, and the user-supplied password as the password attribute. This query succeeds, and thereby authenticates the user, only if the user’s password allows that user to access the directory. In other words, the application uses the user’s LDAP directory password as its own password.

The “Reviewing the code” section that follows describes the code’s function in detail. For more information on using LDAP directories with ColdFusion, seeManaging LDAP Directories

<cflogin>
<!--- setting basic attributes --->
<cfset root = "o=macromedia.com">
<cfset server="ldap.macromedia.com">
<cfset port="389">

<!--- These attributes are used in the first search. --->
<!--- This filter will look in the objectclass for the user's ID. --->
<cfset filter = "(&(objectclass=*)(uid=#Form.UserID#))">
<!--- Need directory manager's cn and password to get the user's
      password from the directory --->
<cfset LDAP_username = "cn=directory manager">
<cfset LDAP_password = "password">

<!--- Search for the user's dn information. This is used later to
      authenticate the user.
        NOTE: Do this as the Directory Manager to ensure access to the
      information --->
<cftry>
   <cfldap action="QUERY"
         name="userSearch"
         attributes="uid,dn"
         start="#root#"
         scope="SUBTREE"
         server="#server#"
         port="#port#"
         filter="#filter#"
         username="#LDAP_username#"
         password="#LDAP_password#"
   >
   <cfcatch type="Any">
      <cfset UserSearchFailed = true>
   </cfcatch>
</cftry>
<!--- If user search failed or returns 0 rows abort --->
<cfif NOT userSearch.recordcount OR UserSearchFailed>
   <cfoutput>
      <script> alert("UID for #uid# not found"); </script>
   </cfoutput>
   <cfabort>
</cfif>

<!--- pass the user's DN and password to see if the user authenticates
      and get the user’s roles>

<cftry>
   <cfldap
      action="QUERY"
      name="auth"
      attributes="dn,roles"
      start="#root#"
      scope="SUBTREE"
      server="#server#"
      port="#port#"
      filter="#filter#"
      username="#userSearch.dn#"
      password="#Form.password#"
   >

   <cfcatch type="any">
      <cfif FindNoCase("Invalid credentials", cfcatch.detail)>
         <cfoutput><script>alert("User ID or Password invalid for user:
#Form.userID#")</script>
         </cfoutput>
         <cfabort>
      <cfelse>
         <cfoutput><script>alert("Unknown error for user: #Form.userID#
#cfcatch.detail#")</script>
         </cfoutput>
         <cfabort>
      </cfif>
   </cfcatch>
</cftry>

<!--- If the LDAP query returned a record, the user is valid. --->
<cfif auth.recordcount>
   <cfloginuser name="#Form.userID#" password="#Form.password#"
roles="#auth.roles#">
</cfif>
</cflogin>


Reviewing the code

The following table describes the code and its function:

Code
Description
<cflogin>
<cfset root = "o=macromedia.com">
<cfset server="ldap.macromedia.com">
<cfset port="389">
<cfset filter = "(&(objectclass=*)
   (uid=#Form.UserID#))">
<cfset LDAP_username =
   "cn=directory manager">
<cfset LDAP_password = "password">
Starts cflogin tag body. Sets several of the values used as attributes in the cfldap tags as variables. This ensures that the same value is used in both tags, and makes it easier to change the settings if needed.
Sets the directory manager’s user name and password for the first query.
<cftry>
   <cfldap action="QUERY"
      name="userSearch"
      attributes="uid,dn"
      start="#root#"
      scope="SUBTREE"
      server="#server#"
      port="#port#"
      filter="#filter#"
      username="#LDAP_username#"
      password="#LDAP_password#"
   >
In a cftry block, uses the directory manager’s identity to get the distinguished name (dn) for the user. If the user ID is not in the directory, returns an empty record set.
   <cfcatch type="Any">
      <cfset UserSearchFailed = true>
   </cfcatch>
</cftry>
Catches any exception. Sets a UserSearchFailed flag to true.
Ends the cftry block.
<cfif NOT userSearch.recordcount OR
      UserSearchFailed>
   <cfoutput>
      <script>
         alert("UID for #uid# not found");
      </script>
   </cfoutput>
   <cfabort>
</cfif>
If the LDAP lookup did not return any results or the UserSearchFailed flag is True, displays an error message and ends processing of the page
<cftry>
   <cfldap
      action="QUERY"
      name="auth"
      attributes="dn,roles"
      start="#root#"
      scope="SUBTREE"
      server="#server#"
      port="#port#"
      filter="#filter#"
      username="#userSearch.dn#"
      password="#Form.password#">
In a try block, uses the distinguished name from the previous query and the user-supplied password to access the directory and get the user’s roles. If either the dn or password is invalid, the cfldap tag throws an error, which is caught in the cfcatch block.
<cfcatch type="any">
   <cfif FindNoCase("Invalid credentials",
     cfcatch.detail)>
      <cfoutput><script>alert("User ID or
         Password invalid for user:
         #Form.userID#")</script>
      </cfoutput>
      <cfabort>
   <cfelse>
      <cfoutput><script>alert("Unknown error for
         user: #Form.userID# #cfcatch.detail#")
         </script></cfoutput>
     <cfabort>
   </cfif>
</cfcatch>
</cftry>
Catches any exceptions.
Tests to see if the error information includes the string "invalid credentials", which indicates that either the dn or password is invalid. If so, displays an error message indicating the problem. Otherwise, displays a general error message.
If an error is caught, the cfabort tag ends processing of the request after displaying the error description.
<cfif auth.recordcount>
   <cfloginuser name="#Form.userID#"
      password="#Form.password#"
   roles="#auth.roles#">
</cfif>
</cflogin>
If the second query returned a valid record, logs in the user and sets the roles to the values returned by the query.
Ends the cflogin tag body.

Previous


Developing Globalized Applications

ColdFusion lets you develop dynamic applications for the Internet. Many ColdFusion applications are accessed by users from different countries and geographical areas. One design detail that you must consider is the globalization of your application so that you can best serve customers in different areas.

This chapter contains information that you can use to develop applications that can be accessible to many different users.

Contents
  • Introduction to globalization
  • About character encodings
  • Locales
  • Processing a request in ColdFusion
  • Tags and functions for globalizing
  • Handling data in ColdFusion
Next


Introduction to globalization

Globalization lets you create application for all of your customers in all the languages that your support. In some cases, globalization can let you accept data input using a different character set than the one you used to implement your application. For example, you can create a website in English that lets customers submit form data in Japanese. Or, you can allow a request URL to contain parameter values entered in Korean.

Your application also can process data containing numeric values, dates, currencies, and times. Each of these types of data can be formatted differently for different countries and regions.

You can also develop applications in language other than English. For example, you can develop your application in Japanese so that the default character set is Shift-JIS, your ColdFusion pages contain Japanese characters, and your interface displays in Japanese.

Globalizing your application requires that you perform one or more of the following actions:

  • Accept input in more than one language
  • Handle dates, times, currencies, and numbers formatted for multiple locales
  • Process data from a form, database, HTTP connection, e-mail message, or other input formatted in multiple character sets
  • Create ColdFusion pages containing text in languages other than English


Defining globalization

You will probably find several different definitions for globalization. For this chapter, globalization is defined as an architectural process where you put as much application functionality as possible into a foundation that can be shared among multiple languages.

Globalization is composed of the following two parts:

  • Internationalization Developing language-neutral application functionality that can recognize, process, and respond to data regardless of its representation. That is, whatever the application can do in one language, it can also do in another. For example, think of copying and pasting text. A copy and paste should not be concerned with the language of the text it operates on. For a ColdFusion application, you may have processing logic that performs numeric calculations, queries a database, or performs other operations independent of language.
  • Localization Taking shared, language-neutral functionality, and applying a locale-specific interface to it. Sometimes this interface is referred to as a skin. For example, you may develop a set of menus, buttons, and dialog boxes for a specific language, such as Japanese, that represent the language-specific interface. You then combine this interface with the language-neutral functionality of the underlying application. As part of localization, you create the functionality to handle input from customers in a language-specific manner and output appropriate responses for that language.


Importance of globalization ColdFusion applications

The Internet has no country boundaries. Customers can access websites from anywhere in the world, at any time, or on any date. Unless you want to lock your customers into using a single language, such as English, to access your site, you should consider globalization issues.

One reason to globalize your applications is to avoid errors and confusion for your customers. For example, a date in the form 1/2/2002 is interpreted as January 2, 2002 in the United States, but as February 1, 2002 in European countries.

Another reason is to display currencies in the correct format. Think of how your customers would feel when they find out the correct price for an item is 15,000 American dollars, not 15,000 Mexican Pesos (about 1600 American dollars).

Your website may also accept customer feedback or some other form of text input. You may want to support that feedback in multiple languages using a variety of character sets.


How ColdFusion supports globalization

ColdFusion is implemented in Java. As a Java application, ColdFusion can leverage many of the inherent globalization features to be an effective web application server. For example, ColdFusion stores all strings internally using the Unicode character encoding. Because it uses Unicode, ColdFusion can represent any text data from any language.

In addition, ColdFusion includes many tags and functions designed to support globalizing your applications. You can use these tags and functions to set locales, convert date and currency formats, control the output encoding of ColdFusion pages, and perform other actions.


Character sets and locales

When you discuss globalization issues, two topics that you must consider are the character sets recognized by the application and the locales for which the application must format data.

A character set is a collection of characters. For example, the Latin alphabet is the character set that you use to write English, and it includes all of the lower- and upper-case letters from A to Z. A character set for French includes the character set used by English, plus special characters such as “é,” “à,” and “ç.”

The Japanese language uses three alphabets: Hiragana, Katakana and Kanji. Hiragana and Katakana are phonetic alphabets that each contain 46 characters plus two accents. Kanji contains Chinese ideographs adapted to the Japanese language. The Japanese language uses a much larger character set than English because Japanese supports more than 10,000 different characters.

In order for a ColdFusion application to process text, the application must recognize the character set used by the text. For more information on character sets, see About character encodings.

A locale identifies the exact language and cultural settings for a user. The locale controls how dates and currencies are formatted, how to display time, and how to display numeric data. For example, the locale English (US) determines that a currency value displays as:

$100,000.00

while a locale of Portuguese (Brazilian) displays the currency as:

R$ 100.000

In order to correctly display date, time, currency, and numeric data to your customers, you must know the customer’s locale. For more information on locales, see Locales.


About character encodings

An encoding maps each character in a character set to a numeric value that can be represented by a computer. These numbers can be represented by a single bytes or multiple bytes. For example, the ASCII encoding uses seven bits to represent the Latin alphabet, punctuation, and control characters.

You use Japanese encodings, such as Shift-JIS, EUC-JP, and ISO-2022-JP, to represent Japanese text. These encodings can vary slightly, but they include a common set of approximately 10,000 characters used in Japanese.

The following terms that apply to character encodings:

  • SBCS single-byte character set such as ASCII
  • DBCS double-byte character set such as Shift-JIS
  • MBCS multiple-byte character set

The following table lists some common character encodings, however, there are many additional character encodings that browsers and web servers support:

Encoding | Type | Description
ASCII | SBCS | 7-bit encoding used by English and Indonesian Bahasa languages
Latin-1 | SBCS | 8-bit encoding used by many Western European languages
Shift-JIS | DBCS | 16-bit Japanese encoding
EUC-KR | DBCS | 16-bit Korean encoding
UCS-2 | DBCS | Two-byte Unicode encoding
UTF-8 | MBCS | ASCII is 7-bit, European characters with diacriticals are two-byte and Asian characters are three-byte

The World Wide Web Consortium maintains a list of all character encodings supported by the Internet. You can find this information at the following URL:

http://www.w3.org/International/O-charset.html


The Unicode character encoding

ColdFusion uses the Java Unicode Standard for representing character data internally. The Unicode Standard Character encoding can represent many major languages, including ASCII, Latin-1, Shift-JIS, and others. Therefore, ColdFusion can input, store, process, and output text from all languages supported by Unicode.

By default, ColdFusion uses UTF-8 to represent text data sent to a browser. UTF-8 converts characters into a variable-length encoding. Most data is sent as a single byte, for ASCII, or as three bytes, for most other languages. One advantages of UTF-8 is that it can be recognized by systems designed to process single-byte ASCII character while being flexible enough to handle multiple-byte character representations.

While the default format of text data output by ColdFusion is UTF-8. you can set the output type of a ColdFusion page to any character set. For example, you can output text using the Japanese language Shift-JIS character set. For more information, see Determining the character set of server output.


Locales

A locale identifies the exact language and cultural settings to use for a user. The locale controls how dates and currencies are formatted, how to display time, and how to display numeric data.

In ColdFusion, a locale is identified by one or more of the elements shown in the following table:

Element | Description
language | This is the basic locale identifier, such as English. This is identified by an ISO 639 two-letter language code.
regional variation | A country code: for example the (US) in English (US). This is identified by an ISO 3166 two-letter country code.
variant | Not commonly used, variants create special locales with additional requirements. A common variant example is the euro variant used by European countries that have adopted the Euro as the currency.


Setting the locale

By default, the ColdFusion locale defaults to the locale of the JVM, which typically defaults to that of the operating system. However, when processing information for a different locale, you must change this default. You can set the locale in the JVM at startup time, or you can use the SetLocale() function within a ColdFusion page.

The SetLocale() function determines the default display format of date, time, number, and currency values. ColdFusion supports 26 locales. For the complete list, see the CFML Reference. You use the GetLocale() function to determine the current locale setting of ColdFusion. If you have not made a call to SetLocale(), GetLocale() returns the locale of the JVM.

Note: In previous versions of ColdFusion, the default locale was always English, not the operating system’s locale. For the Japanese version of ColdFusion, the default was Japanese.

The following example code uses the LSCurrencyFormat() function to output the value 100,000 in monetary units for all the ColdFusion-supported locales. You can run this code to see how the locale affects the data returned to a browser.

<p>LSCurrencyFormat returns a currency value using the locale convention.
<!--- loop through list of locales; show currency values for 100,000 units --->
<cfloop LIST = "#Server.Coldfusion.SupportedLocales#"
index = "locale" delimiters = ",">
<cfset oldlocale = SetLocale(locale)>
   <cfoutput><p><b><I>#locale#</I></b><br>
      Local: #LSCurrencyFormat(100000, "local")#<br>
      International: #LSCurrencyFormat(100000, "international")#<br>
      None: #LSCurrencyFormat(100000, "none")#<br>
      <hr noshade>
   </cfoutput>
</cfloop>

This example uses the ColdFusion variable Server.Coldfusion.SupportedLocales, which contains a list of all supported ColdFusion locales.


Processing a request in ColdFusion

When ColdFusion receives an HTTP request for a ColdFusion page, ColdFusion resolves the request URL to a physical file and reads its contents to parse it. A ColdFusion page can be encoded in a variety of ways, using different character sets and formats.

The following figure shows an example of a client making a request to ColdFusion:

This is a picture of the feature being described.

The content of the ColdFusion page on the server can be static data (typically HTML and plain text not processed by ColdFusion), and dynamic content written in CFML. Static content is written directly to the response to the browser and the dynamic content is processed by ColdFusion.

The default language of a website might be different than from that of the person connecting to it. For example, you could connect to an English website from a French computer. When ColdFusion generates a response, the response must be formatted in the way expected by the customer. This includes both the character set of the response and the locale.

This section describes how ColdFusion determines the character set of the files that it processes, and how it determines the character set and locale of its response to the client.


Determining the character set of a ColdFusion page

When a request for a ColdFusion page occurs, the ColdFusion server opens the page, processes the static (HTML) content, processes the dynamic content (CFML), and returns the results back to the browser of the requestor. In order to process the ColdFusion page, though, ColdFusion has to interpret the page content.

One piece of information used by ColdFusion is the Byte Order Mark (BOM) in a ColdFusion page. The BOM is special a character at the beginning of a text stream that specifies the byte order (big/little endian) used by the page. The following table lists the common BOM values:

Encoding | BOM Signature
UTF-8 | EE BB BF
UTF-16 Big Endian | FE FF
UTF-16 Little Endian | FF FE

To insert a BOM mark in a file, your editor must support BOM marks. Many IDEs support insertion of these character, including Macromedia Dreamweaver MX, however, ColdFusion Studio does not.

If your file does not contain a BOM, or if your IDE does not let you set one, you can use the cfprocessingdirective tag to set the character encoding of the page. However, if you insert the cfprocessingdirective tag on a page that has a BOM, the information specified by the cfprocessingdirective tag must be the same as for the BOM; otherwise ColdFusion issues an error.

The following procedure describes how ColdFusion recognizes the encoding format of a ColdFusion page.

To ColdFusion determines the page encoding:

  1. Use the BOM if specified.

    2. Macromedia recommends that you use BOM marks in your files.

  2. Default to the JVM system encoding.

    3. Typically, the JVM uses the same encoding as the operating system but you can override it.

  3. Use the pageEncoding attribute of the cfprocessingdirective tag if specified.

    4. If a BOM is detected in the file, it throws an error if cfprocessingdirective specifies an encoding different from the BOM.

    If there are multiple occurrences of the cfprocessingdirective tag in the same ColdFusion page, the pageEncoding attribute must specify the same setting or else ColdFusion throws an error.

    If you use the cfprocessingdirective tag, insert it as close to the top of the page as possible; for example, immediately after any cfsetting or cfsilent tag, but before any other logic.

    The cfprocessingdirective tag specifies information to the ColdFusion compiler and is evaluated when ColdFusion compiles the page, not when it executes the page. Therefore, you cannot embed the cfprocessingdirective tag within conditional logic. For example, the following code will not have any effect at execution time since the cfprocessingdirective tag will already have been evaluated:

    <cfif dynEncoding is not "dynamic encoding is not possible">
   <cfprocessingdirective pageencoding=#dynEncoding# />
</cfif>


Determining the character set of server output

As part of servicing an HTTP request, ColdFusion must determine the character set of the data returned in the HTTP response. By default, ColdFusion returns character data using the Unicode UTF-8 format.

However, within a ColdFusion page you can override the default character encoding of the response using the cfcontent tag. Use the type attribute of cfcontent to specify the MIME type of the page output, including the character set, as follows:

<cfcontent type="text/html charset=EUC-JP">

ColdFusion pages (meaning .cfm pages) default to using the Unicode UTF-8 format for the response even if you include the HTML meta tag in the page. Therefore, the following code will not modify the character set of the response:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
           "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type"
content="text/html;
charset="Shift-JIS">
</head>
...

In this example, the response will still use the UTF-8 character set. Use the cfcontent tag to set the output character set.


Tags and functions for globalizing

ColdFusion supplies many tags and functions that you can use to develop globalized applications. This section describes these tags and functions.


Using tags for globalizing applications

The following table shows the tags that you use most often to globalize an application:

Tag | Attributes | Use
cfprocessingdirective | pageencoding | Specify the encoding of a ColdFusion page so ColdFusion can parse it. For an example, see Determining the character set of a ColdFusion page.
cfcontent | type encoding | Specify the encoding of the results returned to the client browser. For an example, see Determining the character set of server output.
cffile | encoding | Specify how to encode data written to or read from a file. For an example, see Reading and writing file data.


Using functions for globalizing applications

ColdFusion contains functions that you use when globalizing an application. These functions include string functions as well as date, time, currency, and numeric functions.


String functions

ColdFusion provides the following functions to process string data:

Function | Function | Function | Function
Asc | Insert | LSParseNumber | REReplace
Chr | JavaCast | LTrim | REReplaceNoCase
CJustify | JSStringFormat | Mid | Reverse
Compare | LCase | MonthAsString | Right
CompareNoCase | Left | ParseDateTime | RJustify
DayOfWeekAsString | Len | REFind | RTrim
Encrypt | LJustify | REFindNoCase | SpanExcluding
FormatBaseN | ListValueCount | RemoveChars | SpanIncluding
Find | ListValueCountNoCase | RepeatString | ToBase64
FindNoCase | LSParseCurrency | Replace | Trim
FindOneOf | LSParseDateTime | ReplaceList | UCase
GetToken | LSParseEuroCurrency | ReplaceNoCase | Val
Hash |  |  |

These functions recognize the Unicode encodings so they operate correctly for all single and double-byte character sets.

Note: Applications developed for previous versions of ColdFusion that assumed that the character length of a string was the same as the byte length might produce errors in ColdFusion MX.


Date, time, currency, and numeric functions

CFML defines versions of the date, time, currency, and numeric functions that support different locales. The names of these functions are prefixed by LS. The following table lists the LS functions and several other functions used with date, time, currency, and numeric data:

Function | Function
DateConvert | LSIsNumeric
GetHttpTimeString | LSNumberFormat
GetLocale | LSParseCurrency
GetTimeZoneInfo | LSParseDateTime
LSCurrencyFormat | LSParseEuroCurrency
LSDateFormat | LSParseNumber
LSEuroCurrencyFormat | LSTimeFormat
LSIsCurrency | SetLocale
LSIsDate |

You must precede calls to the LS functions with a call to the SetLocale() function in order to set the locale. If you do not, these functions default to using the locale defined by the JVM, which typically is the locale of the operating system.

The following example uses the LSDateFormat() function to display the current date in the formats for each locale supported by ColdFusion:

<!--- This example shows LSDateFormat --->
<html>
<head>
<title>LSDateFormat Example</title>
</head>
<body>
<h3>LSDateFormat Example</h3>
<p>Format the date part of a date/time value using the locale convention.
<!--- loop through a list of locales; show date values for Now()--->
<cfloop list = "#Server.Coldfusion.SupportedLocales#"
   index = "locale" delimiters = ",">
   <cfset oldlocale = SetLocale(locale)>

   <cfoutput><p><B><I>#locale#</I></B><br>
      #LSDateFormat(Now(), "mmm-dd-yyyy")#<br>
      #LSDateFormat(Now(), "mmmm d, yyyy")#<br>
      #LSDateFormat(Now(), "mm/dd/yyyy")#<br>
      #LSDateFormat(Now(), "d-mmm-yyyy")#<br>
      #LSDateFormat(Now(), "ddd, mmmm dd, yyyy")#<br>
      #LSDateFormat(Now(), "d/m/yy")#<br>
      #LSDateFormat(Now())#<br>
      <hr noshade>
   </cfoutput>
</cfloop>
</body>
</html>


Handling data in ColdFusion

Many of the issues involved with globalizing applications deal with processing data from the various sources supported by ColdFusion. These sources include:

  • URL strings
  • Forms
  • Files
  • Databases
  • E-mail
  • HTTP
  • LDAP
  • WDDX
  • COM
  • CORBA

This section describes how to handle data from each of these sources.


Input data from URLs and HTML forms

A web application server receives character data from request URL parameters or as form data.

The HTTP 1.1 standard only allows US-ASCII characters (0-127) for the URL specification and for message headers. This requires a browser to encode the non-ASCII characters in the URL, both address and parameters, by escaping (URL encoding) the characters using the “%xx” hexadecimal format. URL encoding, however, does not determine how the URL is used in a web document. It only specifies how to encode the URL.

Form data uses the message headers to specify the encoding used by the request (Content headers) and the encoding used in the response (Accept headers). So content negotiation between the client and server uses this information.

This section contains suggestions on how you can handle both URL and form data entered in different character sets.


Handling URL strings

URL requests to a server often contain name/value pairs as part of the request. For example, the following URL contains name/value pairs as part of the URL:

http://company.com/prod_page.cfm?name=Stephen;ID=7645

As noted in the previous section, URL characters entered in using any character set other than US-ASCII are URL encoded in a hexadecimal format. However, by default, a web server assumes that the characters of a URL string are single byte characters.

One common method used to support different character sets within a URL is to include a name/value pair within the URL that defines the character set of the URL. For example, the following URL uses a parameter called "encoding to define the character set of the URL parameters:

http://company.com/prod_page.cfm?name=Stephen;ID=7645;encoding=Latin-1

Within the product_name.cfm page, you can check the value of the encoding parameter before processing any of the other name/value pairs. This guarantees that you will handle the parameters correctly.

You can also use the setEncoding() function to specify the character set of URL parameters. The setEncoding() function takes two parameters; the first specifies a variable scope and the second specifies the character set used by the scope. Since ColdFusion writes URL parameters to the URL scope, you specify "URL" as the scope parameter to the function.

For example, if the URL parameters were passed using Shift-JIS, you could access them as follows:

<cfscript>
   setEncoding("URL", "Shift_JIS");
   writeoutput(URL.name);
   writeoutput(URL.ID);
</cfscript>


Handling form data

The HTML form tag and the ColdFusion cfform tag allows users to enter text on a page, then submit that text to the server. The form tags are designed to work only with single byte character data though. Since ColdFusion uses two bytes per character when it stores strings, ColdFusion converts each byte of the form input into a two-byte representation.

However, if a user enters double-byte text into the from, the from interprets each byte as a single character, rather than recognize that each character is two bytes. This will corrupt the input text, as the following example shows:

  1. A customer enters three double-byte characters in a form, represented by six bytes.
  2. The form returns the six bytes to ColdFusion as six characters. ColdFusion converts them to a representation using two bytes per input byte for a total of 12 bytes.
  3. Outputting these characters results in corrupt information displayed to the user.

To work around this issue, ColdFusion supplies the setEncoding() function that you use when working with forms. You use this tag to specify the character set of input form text. The setEncoding() function takes two parameters; the first specifies the variable scope and the second specifies the character set used by the scope. Since ColdFusion writes form parameters to the Form scope, you specify "Form" as the scope parameter to the function. If the input text is double byte, ColdFusion preserves the two-byte representation of the text.

For example, the following code specifies that the form data contains Korean characters:

<cfscript>
   setEncoding("FORM", "EUC-KR");
</cfscript>
<h1> Form Test Result </h1>
<strong>Form Values :</strong>

<cfset text =  "String = #form.input1# , Length = #len(Trim(form.input1))#">
<cfoutput>#text#</cfoutput>


Reading and writing file data

You use the cffile tag to write to and read from text files. By default, the cffile tag assumes that you are reading single byte character data. This causes a problem if you read a file that contains double-byte characters, whether it is a file you created using cffile to write to the file, or any file containing double-byte characters.

On a read, the cffile tag converts each byte into a two-byte representation. If the data is a single-byte representation, the read works fine. If the file contains double-byte characters, the read interprets each byte as a single character and corrupts the data.

To enable the cffile tag to correctly read and write double-bye characters, you can pass the charset attribute to it. Specify as a value the character encoding of the data to read or write, as the following example shows:

<cffile action="read"
   charset="EUC-KR"
   file = "c:\web\message.txt"
   variable = "Message" >


Databases

ColdFusion applications access databases using drivers for each of the supported database types. The conversion of client native language data types to SQL data types is transparent and is done by the driver managers, database client, or server. For example, the character data (SQL CHAR, VARCHAR) you use with JDBC API is represented Unicode encoded strings.

Database administrators configure data sources and usually are required to specify the character encodings for character column data. Many of the major vendors, such as Oracle, Sybase, and Informix, support storing character data in many character encodings including the Unicode’s UTF-8 and UTF-16 (UCS-2).

The database drivers supplied with ColdFusion correctly handle data conversions from the database native format to the ColdFusion Unicode format. You should not have to perform any additional processing to access databases. However, you should always check with your database administrator to determine how your database supports different character encodings.


E-Mail

ColdFusion supports e-mail using the tags cfmail and cfmailparam. Because ColdFusion uses the Java mail package, which supports Unicode, you do not have to perform any special processing to handle e-mail.


HTTP

ColdFusion supports HTTP communication using the cfhttp and cfhttpparam tags and the GetHttpRequestData functions.

The cfhttp tag supports making HTTP requests using GET and POST. By default, the cfhttp tag uses the Unicode UTF-8 encoding for passing data. However, you can also insert the cfhttpparam tag to specify a MIME type.


LDAP

ColdFusion supports LDAP through the cfldap tag. LDAP uses the UTF-8 encoding format, so you can mix all retrieved data with other data and safely manipulated it. No extra processing is required to support LDAP.


WDDX

ColdFusion supports cfwddx tag. ColdFusion stores WDDX data as UTF-8 encoding so it automatically supports double-byte character sets. You do not have to perform any special processing to handle double-byte characters with WDDX.


COM

ColdFusion supports COM through the cfobject type="com" tag. All strings data used in COM interfaces are constructed using wide characters (wchars) which support double-byte characters. You do not have to perform any special processing for interfacing with COM objects.


CORBA

ColdFusion supports CORBA through the cfobject type="corba" tag. The CORBA 2.0 interface definition language (IDL) basic type “String” used the Latin-1 character set which used the full 8-bits (256) to represent characters.

As long as you are using CORBA later than version 2.0, which includes support for the IDL types wchar and wstring which map to Java types char and string respectively, you do not have to do anything to support double-byte characters.

However, if you are using a version of CORBA that does not support wchar and wstring, the server uses char and string data types which assume a single byte representation of text.


Searching & Indexing

ColdFusion supports Verity search through the cfindex, cfcollection, and cfsearch tags. To support multilingual searching, ColdFusion includes on the ColdFusion CD Verity language packs that you install to support different languages.

Previous


Debugging and Troubleshooting Applications

ColdFusion provides detailed debugging information to help you resolve problems with your application. This chapter describes how you configure ColdFusion to provide debugging information, how to understand the information it provides, and how to use the cftrace tag to provide detailed information on code execution. It also provides additional information on tools for validating your code before you run it and techniques for troubleshooting particular problems.

Note: Macromedia Dreamweaver MX provides integrated tools for displaying and using ColdFusion debugging output. For information on using these tools, see the Dreamweaver MX Help.

Contents
  • Configuring debugging in the ColdFusion Administrator
  • Using debugging information from browser pages
  • Controlling debugging information in CFML
  • Using the cftrace tag to trace execution
  • Using the Code Analyzer
  • Troubleshooting common problems
Next


Configuring debugging in the ColdFusion Administrator

ColdFusion can provide important debugging information for every application page requested by a browser. The ColdFusion Administrator lets you specify which debugging information to make available and how to display it. The following sections briefly describe the Administrator settings. For more information, see the online Help for the Administrator Debugging pages.


Debugging Settings page

The following options on the Administrator Debugging Settings page determine the information that ColdFusion displays in debugging output:

Option
Description
Enable Debugging
Enables debugging output. When this option is cleared, no debugging information is displayed, including all output of cftrace calls. (Cleared by default.)
You should disable debugging output on production servers. Doing so increases security by ensuring that users cannot see debugging information. It also improves server response times. You can also limit debugging output to specific IP addresses; for more information, see Debugging IP addresses page.
Select Debugging Output Format
Determines how to display debugging output:
  • The classic.cfm template (the default) displays information as plain HTML text at the bottom of the page.
  • The dockable.cfm template uses DHTML to display the debugging information using an expanding tree format in a separate window. This window can be either a floating pane or docked to the browser window. For more information on the dockable output format, see Using the dockable.cfm output format.
Report Execution Times
Lists ColdFusion pages that run as the result of an HTTP request and displays execution times, ColdFusion also highlights in red pages with processing times greater than the specified value, and you can select between a summary display or a more detailed, tree structured, display.
Database Activity
Displays debugging information about access to SQL data sources and stored procedures (Selected by default.).
Exception information
Lists all ColdFusion exceptions raised in processing the request. (Selected by default.)
Tracing information
Displays an entry for each cftrace tag. When this option is cleared, the debugging output does not include tracing information, but the output page does include information for cftrace tags that specify inline="Yes". (Selected by default.)
For more information on using the cftrace tag, seeUsing the cftrace tag to trace execution.
Variables
Enables the display of ColdFusion variable values. When this option is cleared, disables display of all ColdFusion variables in the debugging output. (Selected by default.)
When enabled, ColdFusion displays the values of variables in the selected scopes. You can select to display the contents of any of the ColdFusion scopes except Variables, Attributes, Caller, and ThisTag. To enhance security, Application, Server, and Request variable display is disabled by default,
Enable Robust Exception Information
Enables the display of the following information when ColdFusion displays the exception error page:
  • Path and URL of the page that caused the error
  • Line number and short snippet of the code where the error was identified
  • Any SQL statement and data source
  • Java stack trace
Enable Performance Monitoring
Allows the standard NT Performance Monitor application to display information about a running ColdFusion Application Server.
Enable CFSTAT
Enables you to use of the cfstat command line utility to monitor real-time performance. This utility displays the same information that ColdFusion writes to the NT System Monitor, without using the System Monitor application. For information on the cfstat utility, see Administering ColdFusion MX.

The following figure shows a sample debugging output using the classic output format:

This is a picture of the feature being described.


Debugging IP addresses page

By default, when you enable debugging output, the output is visible only to local users (that is, via IP address 127.0.0.1). You can specify additional IP addresses whose users can see debugging output, or even disable output to local users. Use the Debugging IPs page of the ColdFusion Administrator to specify the addresses that can receive debugging messages.

Note: If you must enable debugging on a production server, for example to help locate the cause of a difficult problem, use the Debugging IP Addresses page to limit the output to your development systems and prevent clients from seeing the debugging information.


Using debugging information from browser pages

The ColdFusion debugging output that you configure in the Administrator displays whenever an HTML request completes. It represents the server conditions at the end of the request. For information on displaying debugging information while a request is processed, see Using the cftrace tag to trace execution.

The following figure shows a sample collapsed debugging output using the dockable.cfm debugging output format. The next sections show each of the debugging sections and describe how you can use the information they display.

This is a picture of the feature being described.


General debugging information

ColdFusion displays general debugging information. In the classic.cfm output format, the information is at the top of the debugging output. In the dockable.cfm output format, it looks as follows:

This is a picture of the feature being described.

(In the classic.cfm output format, the section is first in the debugging output and has no heading.)

The general debugging information includes the following values. The table lists the names used in the classic output template view.

Name | Description
ColdFusion | The ColdFusion Server version.
Template | The requested template. (In the dockable.cfm format, this appears in the Page Overview section and is called Page.)
TimeStamp | The time the request was completed. (In the dockable.cfm format, this appears in the Page Overview section and is called Date.)
Locale | The locality and language that determines how information is processed, particularly the message language.
User Agent | The identity of the browser that made the HTTP request.
Remote IP | The IP address of the client system that made the HTTP request.
Host Name | The name of the host running the ColdFusion server that executed the request.


Execution Time

The Execution Time section displays the time required to process the request. It displays information about the time required to process all pages required for the request, including the Application.cfm and OnRequestEnd.cfm pages, if used, and any CFML custom tags, pages included by the cfinclude tag, and any ColdFusion component (CFC) pages. You can display the execution time in two formats:

  • Summary
  • Tree

Note: Execution tine decreases substantially between the first and second time you use a page after creating it or changing it. The first time ColdFusion uses a page it compiles the page into Java bytecode, which the server saves and loads into memory. Subsequent uses of unmodified pages do not require recompilation of the code, and therefore are substantially faster.


Summary execution time format

The summary format displays one entry for each ColdFusion page processed during the request. If a page is processed multiple times it appears only once in the summary. For example, if a custom tag gets called three time in a request, it appears only once in the output. The summary format looks as follows in the classic.cfm output format:

This is a picture of the feature being described.

The following table describes the display fields:

Column | Description
Total Time | The total time required to process all instances of the page and all pages that it uses. For example, if a request causes a page to be processed two times, and the page includes another page, the total time includes the time required to process both pages twice.
Avg Time | The average time for processing each instance of this page and the pages that it uses. The Avg Time multiplied by the Count equals the Total Time.
Count | The number of times the page is processed for the request.
Template | The path name of the page.

The page icon indicates the requested page.

Any page with an average processing time that exceeds the highlight value that you set in the ColdFusion Administrator Debugging Settings page appears in red.

The last line of the output displays the time that ColdFusion required total time field describe the total time ColdFusion took to parse, compile, and load pages, and to start and end page processing. This figure is not included in the individual page execution times.


Tree execution time format

The tree execution time format is a hierarchical, detailed view of how ColdFusion processes each page. If a page includes or calls second page, the second page appears below and indented relative to the page that uses it. Each page appears once for each time it is used. Therefore, if a page gets called three times in processing a request, it appears three times in the tree. Therefore the tree view displays both processing times and an indication of the order of page processing.

The tree format looks as follows in the dockable.cfm output format:

This is a picture of the feature being described.

As in the summary view, the execution times (in parentheses) show the times to process the listed page and all pages required to process the page, that is, all pages indented below the page in the tree.

By looking at this output in this figure you can determine the following information:

  • ColdFusion took 10 ms to process an Application.cfm page as part of the request.
  • The requested page was tryinclude.cfm. It took 1502 ms to process this page and all pages required to execute it. The other pages took about 1330 (430 + 711 + 191) ms to process, so the code on tryincludme.cfm took about 170 ms.
  • The tryinclude.cfm directly called or included three pages, mytag1.cfm, includeme.cfm, and mytag2.cfm.
  • The includeme.cfm page directly called or included one page, mytag1.cfm.
  • The mytag1.cfm page directly called or included one page, mytag2.cfm
  • The mytag2.cfm page takes about 200 ms to process.
  • The mytag1.cfm page took about 450 ms to process. This time included the 200 ms for mytag2.cfm, so the code on mytag1.cfm took about 250 ms to process.
  • The includeme.cfm page took about 700 ms to process. This time included about 480 ms for processing other pages, so the code on this page took about 220 ms.
  • ColdFusion took 70 ms for processing that was not associated with a specific page.
  • The total processing time was 1582 (10 + 1502 + 70) milliseconds.


Database Activity

When Database Activity is selected on the ColdFusion Administrator Debugging Settings page, the debugging output includes information about database access.


SQL Queries

The SQL Queries section provides information about tags that generate SQL queries or result in retrieving a cached database query: cfquery, cfinsert, cfgridupdate, and cfupdate. The section looks as follows in the dockable.cfm output format:

This is a picture of the feature being described.

The output displays the following information:

  • Page on which the query is located.
  • The time when the query was made.
  • Query name.
  • An indicator if the result came from a cached query.
  • SQL statement, including the results of processing any dynamic elements such as CFML variables and cfqueryparam tags. This information is particularly useful because it shows the results of all ColdFusion processing of the SQL statement.
  • Datasource name.
  • Number of records returned; 0 indicates no match to the query.
  • Query execution time.
  • Any query parameters values from cfqueryparam tags.


Stored Procedures

The stored procedures section displays information about the results of using the cfstoredproc tag to execute a stored procedure in a database management system.

The Stored Procedures section looks as follows in the classic.cfm output format:

This is a picture of the feature being described.

The output displays the following information:

  • Stored procedure name
  • Datasource name
  • Query execution time
  • Page on which the query is located.
  • The time when the query was made.
  • A table displaying the procedure parameters sent and received, as specified in the cfprocparam tags, including the ctype, CFSQLType, value variable, and dbVarName attributes. The variable information for OUT and INOUT parameters includes the returned value.
  • A table listing the procedure result sets returned, as specified in the cfprocresult tag.


Exceptions

When Exception Information is selected on the ColdFusion Administrator Debugging Settings page, the debugging output includes a list of all ColdFusion exceptions raised in processing the application page. This section looks as follows when displaying information about an exception thrown by the cfthrow tag using the dockable.cfm output format:

This is a picture of the feature being described.

The exception information includes information about any application exceptions that are caught and handled by your application code or by the ColdFusion Server.

Exceptions represent events that disrupt the normal flow of an application. You should catch and, whenever possible, recover from forseeable exceptions in your application, as described in Handling Errors. However, you might also want to be alerted to caught exceptions when you are debugging your application. For example, if a file is missing, your application can catch the cffile exception and use a backup or default file instead. If you enable exception information in the debugging output, you can immediately see when this happens.


Trace points

When Tracing Information is selected on the ColdFusion Administrator Debugging Settings page, the debugging output includes the results of all cftrace tags, including all tags that display their results in-line. Therefore, the debugging output contains a historical record of all trace points encountered in processing the request. This section looks as follows when you use the classic.cfm output format:

This is a picture of the feature being described.

For more information on using the cftrace tag, see Using the cftrace tag to trace execution.


Scope variables

When the Variables option and one or more variable scopes are selected on the ColdFusion Administrator Debugging Settings page, the debugging output displays the values of all variables in the selected scopes. The debugging output displays the values that result after all processing of the current page

By displaying selected scope variables you can determine the effects of processing on persistent scope variables, such as Application variables. This can help you locate problems that do not generate exceptions.

The Form, URL, and CGI scopes are useful for inspecting the state of a request. They let you inspect parameters that affect page behavior, as follows:

  • URL variables Identify the HTTP request parameters.
  • Form variables Identify the form fields posted to an action page.
  • CGI variables Provide a view of the server environment following the request.

Similarly, the Client, Session, Application, and Server scope variables show the global state of the application, and can be useful in tracing how each page affects the state of the ColdFusion persistent variables.


Using the dockable.cfm output format

The dockable.cfm output format has several features that are not included in the classic.cfm debugging display, as shown in the following figure of a docked debug pane.

This is a picture of the feature being described.


Application page selections

ColdFusion displays two buttons at the bottom of each page, as described in the following table:

Button | Description
Debug This page | Tells ColdFusion to display the debugging information for the selected frame. Refreshes the debug pane if you select it for the current frame (or the application does not use frames).
Floating/Docked debug pane | Toggles the display between a floating window and a pane docked to the left of the selected frame.


Debug pane features

The debug pane has the following features:

  • You can expand and collapse each debugging information category, such as Exceptions, by clicking on the plus or minus sign (+ or -) in front of each category heading. You can also expand and collapse each scope data type display in the Scoped Variables section.
  • The top of the debug pane displays the URL of the application page being debugged (as identified by the cgi.script_name variable). Click this link to refresh the page and display the debugging information that results. (You can also refresh the page and debugging information by using your browser’s Refresh button or key.)
  • The debug pane also displays a box where you can enter a page pathname or URL. When you click the Go button, ColdFusion processes the page and the debug pane is updated with the debugging information for the new page.


Controlling debugging information in CFML

The following sections describe how you can use CFML tags and functions to display or hide debugging and tracing information.


Generating debugging information for an individual query

The cfquery tag debug attribute overrides the Database Activity setting on the ColdFusion Administrator Debugging Settings page. The debug attribute has an effect only when debugging output is enabled on the Debugging Settings page, as follows:

  • If Database Activity is selected in the Administrator, specify debug="No" to prevent ColdFusion from displaying the query’s SQL and statistics in the debugging output.
  • If Database Activity is not selected in the Administrator, specify debug="Yes" or debug to have ColdFusion display the query’s SQL and statistics in the debugging output.

For example, if Database Activity is not selected in the Administrator, you can use the following code to show the query execution time, number of records returned, ColdFusion page, timestamp, and the SQL statement sent to the data source for this query only:

<cfquery name="TestQuery" datasource="CompanyInfo" debug>
   SELECT * FROM TestTable
</cfquery>

The debug attribute can be useful to disable query debugging information generated by queries in custom tags that you call frequently, so that you only see the debugging information for queries in pages that call the tags.

You can also view stored procedure-specific debugging information by specifying the debug attribute in the cfstoredproc tag.


Controlling debugging output with the cfsetting tag

Use the cfsetting tag showDebugOutput attribute to turn off debugging output for a specific page. The attribute controls debugging output only if the ColdFusion Administrator Debugging Settings page enables debugging output. The attribute’s default value is Yes. The following tag suppresses all debugging output for the current page:

<cfsetting showDebugOutput="No">

You can put this tag on your Application.cfm page to suppress all debugging output for an application, and override it on specific pages by setting showDebugOutput="Yes" in cfsetting tags on those pages. Conversely, you can leave debugging on for the application, and use the cfsetting showDebugOutput="No" tag to suppress debugging on individual pages where the output could cause errors or confusion.

You can also use the showDebugOutput attribute to control debugging output if you do not have access to the ColdFusion Administrator, but only if the Administrator enables debugging.


Using the IsDebugMode function to run code selectively

The IsDebugMode function returns True if debugging is enabled. You can use this function in a cfif tag condition to selectively run code only when debugging output is enabled. The IsDebugMode function lets you tell ColdFusion to run any code in debug mode, so it provides more flexibility than the cftrace tag for processing and displaying information.

You can use the IsDebugMode function to selectively log information only when debugging is enabled. Because you control the log output, you have the flexibility of silently logging information without displaying trace information in the browser. For example, the following code logs the application page, the current time, and the values of two variables to the log file MyAppSilentTrace.log when debugging is enabled:

<cfquery name="MyDBQuery" datasource="CompanyInfo">
   SELECT *
   FROM Employee
</cfquery>
<cfif IsDebugMode()>
   <cflog file="MyAppSilentTrace" text="Page: #cgi.script_name#,
completed query MyDBQuery; Query Execution time:
#cfquery.ExecutionTime# Status: #Application.status#">
</cfif>

Tip: If you use cfdump tags frequently for debugging, put them in <cfif IsDebugMode()> tags; for example <cfif IsDebugMode()><cfdump var=#myVar#></cfif>. This way you ensure that if you leave any cfdump tags in production code, they are not displayed when you disable debugging output.


Using the cftrace tag to trace execution

The cftrace tag displays and logs debugging data about the state of your application at the time the cftace tag executes. You use it to provide “snapshots” of specific information as your application runs.


About the cftrace tag

The cftrace tag provides the following information:

  • A severity identifier specified by the cftrace tag type attribute
  • A timestamp indicating when the cftrace tag executed
  • The time elapsed between the start of processing the request and when the current cftrace tag executes.
  • The time between any previous cftrace tag in the request and the current one. If this is the first cftrace tag processed for the request, the output indicates “1st trace”. ColdFusion does not display this information in inline trace output, only the log and in the standard debugging output.
  • The name of the page that called the cftrace tag
  • The line on the page where the cftrace call is located
  • A trace category specified by the category attribute
  • A message specified by the text attribute
  • The name and value, at the time the cftrace call executes, of a single variable specified by the var attribute

A typical cftrace tag might look like the following:

<cftrace category="UDF End" inline = "True" var = "MyStatus"
text = "GetRecords UDF call has completed">

You can display the cftrace tag output in either or both of the following ways:

  • As a section in the debugging output To display the trace information in the debugging output, select Tracing Information on the ColdFusion Administrator Debugging Settings page.
  • In-line in your application page When you specify the inline attribute in a cftrace tag, ColdFusion displays the trace output on the page at the cftrace tag location. (An inline cftrace tag does not display any output if it is inside a cfsilent tag block.)

The cftrace tag executes only if you select Enable Debugging on the ColdFusion Administrator Debugging Settings page. To display the trace results in the debugging output, you must also specify Tracing Information on the Debugging Settings page; otherwise, the trace information is logged and inline traces are displayed, but no trace information appears in the debugging output.

Note: When you use in-line trace tags, ColdFusion sends the page to the browser after all page processing is completed, but before it displays the debugging output from the debug template. As a result, if an error occurs after a trace tag but before the end of the page, ColdFusion might not display the trace for that tag.

An in-line trace messages look like the following:

This is a picture of the feature being described.

The following table lists the displayed information:

Entry
Meaning
  This is a picture of the feature being described.
Trace type (severity) specified in the cftrace call; in this case, Information.
[CFTRACE 13:21:11.011]
Time when the cftrace tag executed.
[501 ms]
Time taken for processing the current request to the point of the trace tag.
[C:\CusionMX\wwwroot\MYStuff\
NeoDocs\tractest.cfm]
Path in the web server of the page that contains the cftrace tag.
@ line:14
The line number of the cftrace tag.
[UDF End]
Value of the cftrace tag category attribute.
GetRecords UDF call has completed
The cftrace tag text attribute with any variables replaced with their values.
MyStatus Success
Name and value of the variable specified by the cftrace tag var attribute.

ColdFusion logs all cftrace output to the file logs\cftrace.log in your ColdFusion installation directory.

A log file entry looks like the following:

"Information","web-29","04/01/02","13:21:11","MyApp","[501 ms (1st trace)]
[C:\CFusionMX\wwwroot\MYStuff\NeoDocs\tractest.cfm @ line: 14] - [UDF
End] [MyStatus = Success] GetRecords UDF call has completed "

This entry is in standard ColdFusion log format, with comma-delimited fields inside double quote characters. The information displayed in the trace output is in the last, message, field.

The following table lists the contents of the trace message and the log entries. For more information on the log file format, see Logging Errors with the cflog tag.

Entry
Meaning
Information
The Severity specified in the cftrace call.
web-29
Server thread that executed the code.
04/01/02
Date the trace was logged.
13:21:11
Time the trace was logged.
MyApp
The application name, as specified in a cfapplication tag.
501 ms (1st
trace)]
The time ColdFusion took to process the current request up to the cftrace tag, This is the first cftrace tag processed in this request. If there had been a previous cftrace tag, the parentheses would contain the number of milliseconds between when the previous cftrace tag ran and when this tag ran.
[C:\CFusionMX\wwwr
oot\MYStuff\NeoDoc
s\tractest.cfm @
line: 14]
Path of the page on which the trace tag is located and the line number of the cftrace tag on the page.
[UDF End]
Value of the cftrace tag category attribute.
[MyStatus =
Success]
Name and value of the variable specified by the cftrace tag var attribute. If the variable is a complex data type, such as an array or structure, the log contains the variable value and the number of entries at the top level of the variable, such as the number of top-level structure keys.
GetRecords UDF
call has completed
The cftrace tag text attribute with any variables replaced with their values.


Using tracing

As its name indicates, the cftrace tag is designed to help you trace the execution of your application. It can help you do any of several things:

  • You can time the execution of a tag or code section. This capability is particularly useful for tags and operations that can take substantial processing time. Typical candidates include all ColdFusion tags that access external resources, including cfquery, cfldap, cfftp, cffile, and so on. To time execution of any tag or code block, call the cftrace tag before and after the code you want to time.
  • You can display the values of internal variables, including data structures. For example, you can display the raw results of a database query.
  • You can display an intermediate value of a variable. For example, you could use this tag to display the contents of a raw string value before you use string functions to select a substring or format it.
  • You can display and log processing progress. For example, you can put a cftrace call at the head of pages in your application or before critical tags or calls to critical functions. (Doing this could result in massive log files in a complex application, so you should use this technique with care.)
  • If a page has many nested cfif and cfelseif tags you can put cftrace tags in each conditional block to trace the execution flow. When you do this, you should use the condition variable in the message or var attribute.
  • If you find that the ColdFusion Server is hanging, and you suspect a particular block of code (or call to a cfx tag, COM object, or other 3rd party component), you can put a cftrace tag before and after the suspect code, to log entry and exit.


Calling the cftrace tag

The cftrace tag takes the following attributes. All attributes are optional.

Attribute
Purpose
abort
A Boolean value. If you specify True, ColdFusion stops processing the current request immediately after the tag. This attribute is the equivalent of placing a cfabort tag immediately after the cftrace tag. The default is False.If this attribute is True, the output of the cftrace call appears only in the cftrace.log file. The line in the file includes the text “[ABORTED]”.
category
A text string specifying a user-defined trace type category. This attribute lets you identify or process multiple trace lines by categories. For example, you could sort entries in a log according to the category.
The category attribute is designed to identify the general purpose of the trace point. For example, you might identify the point where a custom tag returns processing to the calling page with a “Custom Tag End” category. You can also use finer categories; for example, by identifying the specific custom tag name in the category.
You can include simple ColdFusion variables, but not arrays, structures, or objects, in the category text by enclosing the variable name in pound signs (#).
inline
A Boolean value. If you specify True, ColdFusion displays trace output in-line in the page. The default is False.
The inline attribute lets you display the trace results at the place that the cftrace call is processed. This provides a visual cue directly in the ColdFusion page display.
Trace output also appears in a section in the debugging information display.
text
A text message describing this trace point. You can include simple ColdFusion variables, but not arrays, structures, or objects, in the text output by enclosing the variable name in pound signs (#).
type
A ColdFusion logging severity type. The inline trace display and dockable.cfm output format show a symbol for each type. The default debugging output shows the type name, which is also used in the log file. The type name must be one of the following:

This is a picture of the feature being described. Information (default)

This is a picture of the feature being described. Warning

This is a picture of the feature being described. Error

This is a picture of the feature being described. Fatal Information

var
The name of a single variable that you want displayed. This attribute can specify a simple variable, such as a string, or a complex variable, such as a structure name. Do not surround the variable name in pound signs.
Complex variables are displayed in inline output in cfdump format; the debugging display and log file report the number of elements in the complex variable, instead of any values.
You can use this attribute to display an internal variable that the page does not normally show, or an intermediate value of a variable before the page processes it further.
If you want to display a function return value, put the function inside the message. Do not use the function in the var attribute, because the attribute cannot evaluate functions.

Note: If you specify inline trace output, and a cftrace tag is inside a cfsilent tag block, ColdFusion does not display the trace information in line, but does include it in the standard debugging display.

The following cftrace tag displays the information shown in the example output and log entry in the About the cftrace tagsection:

<cftrace abort="False" category="UDF End" inline = "True" text = "GetRecords UDF
   call has completed" var = "MyStatus">


Using the Code Analyzer

The Code Analyzer has two purposes:

  • It can validate your application’s CFML syntax. To do so, the analyzer runs the ColdFusion compiler on your pages, but does not execute the compiled code. It reports errors that the compiler encounters.
  • It can identify places where ColdFusion MX might behave differently than previous versions. The analyzer identifies the following kinds of features:
    • No longer supported Their use results in errors. For example, ColdFusion now generates an error if you use the cflog tag with the thread="Yes" attribute.
    • Deprecated They are still available, but their use is not recommended and the they might not be available in future releases. Deprecated features might also behave differently now than in previous releases. For example, the cfservlet tag is deprecated.
    • Modified behavior They might behave differently than in previous versions. For example, the StructKeyList function no longer lists the structure key names in alphabetical order.

      • The analyzer provides information about the incompatibility and its severity, and suggests a remedy where one is required.

You can run the Code Analyzer from the ColdFusion Administrator. Select Code Analyzer from the list of Debugging & Logging pages.

Note: The CFML analyzer does not execute the pages that it checks. Therefore, it cannot detect invalid attribute combinations if the attribute values are provided dynamically at runtime.

For more information on using the CFML Code Analyzer see Migrating ColdFusion 5 Applications.


Troubleshooting common problems

This section describes a few common problems that you might encounter and ways to resolve them.

For more information on troubleshooting ColdFusion, see the Macromedia ColdFusion Support Center Testing and Troubleshooting page at http://www.macromedia.com/support/coldfusion/troubleshoot.html. For common tuning and precautionary measurements that can help you prevent technical problems and improve application performance, see the ColdFusion tech tips article, TechNote number 13810. A link to the article is located near the top of the Testing and Troubleshooting page.


CFML syntax errors

Problem: You get an error message such as the following:

Encountered "function or tag name" at line 12, column 1.
Encountered "\"" at line 37, column 20.
Encountered "," at line 24, column 61.
Unable to scan the character '\"' which follows "" at line 38, column 53.

These errors typically indicate that you have unbalanced <, ", or # characters. One of the most common coding errors is to forget to close quoted code, pound sign-delimited variable names, or opening tags. Make sure the code in the identified line and previous lines do not have missing characters.

Note that the line number in the error message often does not identify the line that causes the error. Instead, it identifies the first line where the ColdFusion compiler encountered code that it could not handle as a result of the error.

Problem: You get an error message you do not understand.

Make sure all your CFML tags have matching end tags where appropriate. It is a common error to omit the end tag for the cfquery, cfoutput, cftable, or cfif tag.

As with the previous problem, the line number in the error message often does not identify the line that causes the error, but the first line where the ColdFusion compiler encounters code that it could not handle as a result of the error. Whenever you have an error message that does not appear to report a line with an error, check the code that precedes it for missing text.

Problem: Invalid attribute or value.

If you use an invalid attribute or attribute values, ColdFusion returns an error message. To prevent such syntax errors, use the CFML Code Analyzer. Also see Using the cftrace tag to trace execution.

Problem: You suspect that there are problems with the structure or contents of a complex data variable, such as a structure, array, query object, or WDDX-encoded variable.

Use the cfdump tag to generate a table-formatted display of the variable’s structure and contents. For example, to dump a structure named relatives, use the following line. Note that you must surround the variable name with pound signs (#).

<cfdump var=#relatives#>


Data source access and queries

Problem: You cannot make a connection to the database.

You must create the data source before you can connect. Connection errors can include problems with the location of files, network connections, and database client library configuration.

Create data sources before you refer to them in your application source files. Verify that you can connect to the database by clicking the Verify button on the Data Sources page of the ColdFusion Administrator. If you are unable to make a simple connection from that page, you might need to consult your database administrator to help solve the problem.

Also, check the spelling of the data source name.

Problem: Queries take too long.

Copy and paste the query from the Queries section of the debugging output into your database's query analysis tool. Then retrieve and analyze the execution plan generated by the database server's query optimizer. (The method for doing this varies from dbms to dbms.) The most common cause of slow queries is the lack of a useful index to optimize the data retrieval. In general, avoid table scans (or "clustered index" scans) whenever possible.


HTTP/URL

Problem: ColdFusion cannot correctly decode the contents of your form submission.

The method attribute in forms sent to the ColdFusion Server must be Post, for example:

<form action="test.cfm" method="Post">

Problem: The browser complains or does not send the full URL string when you include spaces in URL parameters.

Some browsers automatically replace spaces in URL parameters with the %20 escape sequence, but others might display an error or just send the URL string up to the first character (as does Netscape 4.7).

URL strings cannot have embedded spaces. Use a plus sign (+) or the standard HTTP space character escape sequence, (%20) wherever you want to include a space. ColdFusion correctly translates these elements into a space.

A common scenario in which this error occurs is when you dynamically generate your URL from database text fields that have embedded spaces. To avoid this problem, include only numeric values in the dynamically generated portion of URLs.

Or, you can use the URLEncodedFormat function, which automatically replaces spaces with %20 escape sequences. For more information on the URLEncodedFormat function, see the CFML Reference.

Previous


Introduction to Databases and SQL

ColdFusion allows you to create dynamic applications to access and modify data stored in a database. You do not need a thorough knowledge of databases to develop ColdFusion applications, but you must know some basic concepts and techniques. This chapter contains an overview of many important database and SQL concepts.

This chapter does not contain a complete description of database theory and SQL syntax. Each database server (such as SQL Server, Oracle, or DB2) has unique capabilities and properties. For more information, see the documentation that ships with your database server.

Contents
  • What is a database?
  • Using SQL
  • Writing Queries Using an Editor
Next


What is a database?

A database defines a structure for storing information. Databases are typically organized into tables, which are collections of related items. You can think of a table as a grid of columns and rows. ColdFusion works primarily with relational databases, such as Oracle, DB2, and SQL Server.

The following figure shows the basic layout of a database table:

This is a picture of the feature being described.

A column defines one piece of data stored in all rows of the table. A row contains one item from each column in the table.

For example, a table might contain the ID, name, title, and other information for individuals employed by a company. Each row, called a data record, corresponds to one employee. The value of a column within a record is referred to as a record field.

The following figure shows an example table, named employees, containing information about company employees:

This is a picture of the feature being described.

The record for employee 4 contains the following field values:

  • LastName field is "Smith"
  • FirstName field is "John"
  • Title field is "Engineer"

This example uses the EmpID field as the table’s primary key field. The primary key contains a unique identifier to maintain each record's unique identity. Primary keys field can include an employee ID, part number, or customer number. Typically, you specify which column contains the primary key when you create a database table.

To access the table to read or modify table data, you use the SQL programming language. For example, the following SQL statement returns all rows from the table where the department ID is 3:

SELECT * FROM employees WHERE DEPTID=3

Note: In this chapter, SQL keywords and syntax are always represented by uppercase letters. Table and column names used mixed uppercase and lowercase letters.


Using multiple database tables

In many database designs, information is distributed to multiple tables. The following figure shows two tables, one for employee information and one for employee addresses:

This is a picture of the feature being described.

In this example, each table contains a column named EmpID. This column associates a row of the employees table with a row in the addresses table.

For example, to obtain all information about an employee, you request a row from the employees table and the row from the addresses table with the same value for EmpID.

One advantage of using multiple tables is that you can add tables containing new information without modifying the structure of your existing tables. For example, to add payroll information, you add a new table to the database where the first column contains the employee’s ID and the columns contain current salary, previous salary, bonus payment, and 401(k) percent.

Also, an access to a small table is more efficient than an access to a large table. Therefore, if you update the street address of an employee, you update only the addresses table, without having to access any other table in the database.


Database permissions

In many database environments, a database administrator defines the access privileges for users accessing the database, usually through username and password. When a person attempts to connect to a database, the database ensures that the username and password are valid and then imposes access requirements on the user.

Privileges can restrict user access so that a user can do the following:

  • Read data
  • Read data and add rows
  • Read data, add rows, modify existing tables

In ColdFusion, you use the ColdFusion administrator to define database connections, called data sources. As part of defining these connections, you specify the username and password used by ColdFusion to connect to the database. The database can then control access based on this username and password.

For more information on creating a data source, see the ColdFusion Administration book.


Commits, rollbacks, and transactions

Before you access data stored in a database, it is important to understand several database concepts, including:

  • Commit
  • Rollback
  • Transactions

A database commit occurs when you make a permanent change to a database. For example, when you write a new row to a database, the write does not occur until the database commits the change.

Rollback is the process of undoing a change to a database. For example, if you write a new row to a table, you can rollback the write up to the point where you commit the write. After the commit, you can no longer rollback the write.

Most databases support transactions where a transaction consists of one or more SQL statements. Within a transaction, your SQL statements can read, modify, and write a database. You end a transaction by either committing all your changes within the transaction or rolling back all of them.

Transactions can be useful when you have multiple writes to a database and want to make sure all writes occurred without error before committing them. In this case, you wrap all writes within a single transaction and check for errors after each write. If any write causes an error, you rollback all of them. If all writes occur successfully, you commit the transaction.

A bank might use a transaction to encapsulate a transfer from one account to another. For example, if you transfer money from your savings account to your checking account, you do not want the bank to debit the balance of your savings account unless it also credits your checking account. If the update to the checking account fails, the bank can rollback the debit of the savings account as part of the transaction.

ColdFusion includes the cftransaction tag that allows you to implement database transactions for controlling rollback and commit. For more information, see the CFML Reference.


Database design guidelines

From this basic description, a few database design rules emerge:

  • Each record should contain a unique identifier as the primary key such as an employee ID, a part number, or a customer number. The primary key is typically the column used to maintain each record's unique identity among the tables in a relational database. Databases allow you to use multiple columns for the primary key.
  • When you define a column, you define a SQL data type for the column, such as allowing only numeric values to be entered in the salary column.
  • Assessing user needs and incorporating those needs in the database design is essential to a successful implementation. A well-designed database accommodates the changing data needs within an organization.

The best way to familiarize yourself with the capabilities of your database product or database management system (DBMS) is to review the product documentation.


Using SQL

This section introduces SQL, describes basic SQL syntax, and contains examples of SQL statements. It provides enough information for you to begin using ColdFusion. However, this section does not contain an exhaustive description of the entire SQL programming language. For complete SQL information, see the SQL reference that ships with your database.

A query is a request to a database. The query can ask for information from the database, write new data to the database, update existing information in the database, or delete records from the database.

The Structured Query Language (SQL) is an ANSI/ISO standard programming language for writing database queries. All databases supported by ColdFusion support SQL and all ColdFusion tags that access a database allow you to pass SQL statements to the tag.


SQL example

The most commonly used SQL statement in ColdFusion is the SELECT statement. The SELECT statement reads data from a database and returns it to ColdFusion. For example, the following SQL statement reads all the records from the employees table:

SELECT * FROM employees

You interpret this statement as "Select all rows from the table employees" where the wildcard symbol * corresponds to all rows.

Tip: If you are using Dreamweaver MX, ColdFusion Studio, or HomeSite+ you can use the built-in query builder to build SQL statements graphically by selecting the tables and records to retrieve. For more information, see Writing Queries Using an Editor.

In many cases, you do not want all rows from a table, but only a subset of rows. The next example returns all rows from the employees table, where the value of the DeptID column for the row is 3:

SELECT * FROM employees WHERE DeptID=3

You interpret this statement as "Select all rows from the table employees where the DeptID is 3".

SQL also lets you specify the table columns to return. For example, instead of returning all columns in the table, you can return a subset of columns:

SELECT LastName, FirstName FROM employees WHERE DeptID=3

You interpret this statement as "Select the columns FirstName and LastName from the table employees where the DeptID is 3".

In addition to with reading data from a table, you can write data to a table using the SQL INSERT statement. The following statement adds a new row to the employees table:

INSERT INTO employees(EmpID, LastName, Firstname)
VALUES(51, 'Doe', 'John')


Basic SQL syntax elements

The following sections briefly describes the main SQL command elements.


Statements

A SQL statement always begins with a SQL verb. The following keywords identify commonly used SQL verbs:

Keyword | Description
SELECT | Retrieves the specified records
INSERT | Adds a new row
UPDATE | Changes values in the specified rows
DELETE | Removes the specified rows


Statement clauses

Use the following keywords to refine SQL statements:

Keyword | Description
FROM | Names the data tables for the operation
WHERE | Sets one or more conditions for the operation
ORDER BY | Sorts the result set in the specified order
GROUP BY | Groups the result set by the specified select list items


Operators

The following basic operators specify conditions and perform logical and numeric functions:

Operator | Description
AND | Both conditions must be met
OR | At least one condition must be met
NOT | Exclude the condition following
LIKE | Matches with a pattern
IN | Matches with a list of values
BETWEEN | Matches with a range of values
= | Equal to
<> | Not equal to
< | Less than
> | Greater than
<= | Less than or equal to
>= | Greater than or equal to
+ | Addition
- | Subtraction
/ | Division
* | Multiplication


Case sensitivity with databases

ColdFusion is a case-insensitive programming environment. Case insensitivity means the following statements are equivalent:

<cfset foo="bar">

<CFSET FOO="BAR">
<CfSet FOO="bar">

However, many databases, especially UNIX databases, are case sensitive. Case sensitivity means that you must match exactly the case of all column and table names in SQL queries.

For example, the following queries are not equivalent on a case-sensitive database:

SELECT LastName FROM EMPLOYEES
SELECT LASTNAME FROM employees

In a case-sensitive database, employees and EMPLOYEES are two different tables.

For information on how your database handles case, see the product documentation.


SQL notes and considerations

When writing SQL in ColdFusion, keep the following guidelines in mind:

  • There is a lot more to SQL than what is covered here. It is a good idea to purchase one or several SQL guides for reference.
  • The data source, columns, and tables that you reference must exist in order to perform a successful query.
  • Some DBMS vendors use nonstandard SQL syntax (known as a dialect) in their products. ColdFusion does not validate the SQL; it is passed on to the database for validation, so you are free to use any syntax that is supported by your database. Check your DBMS documentation for nonstandard SQL usage.


Reading data from a database

You use the SQL SELECT statement to read data from a database. The SQL statement has the following general syntax:

SELECT column_names
FROM table_names
[ WHERE search_condition ]
[ GROUP BY group_expression ] [HAVING condition]
[ ORDER BY order_condition [ ASC | DESC ] ]

The statements within square brackets are optional.

Note: There are additional options to SELECT depending on your database. For a complete syntax description for SELECT, see the product documentation.

This section describes options to the SELECT statement.


Results of a SELECT statement

When the database processes a SELECT statement, it returns a record set containing the requested data. The format of a record set is a table with rows and columns. For example, if you write the query:

SELECT * FROM employees WHERE DeptID=3

The query returns the following table:

This is a picture of the feature being described.

Since the data returned to ColdFusion by a SELECT statement is in the form of a database table, ColdFusion lets you write a SQL query on the returned results. This functionality is called query of queries. For more information on query of queries, see Accessing and Retrieving Data.

The next example uses a SELECT statement to return only a specific set of columns from a table:

SELECT LastName, FirstName FROM employees WHERE DeptID=3

The query returns the following table:

This is a picture of the feature being described.


Filtering results

The SELECT statement lets you filter the results of a query to return only those records that meet specific criteria. For example, if you want to access all database records for employees in department 3, you use the following query:

SELECT * FROM employees WHERE DeptID=3

You can combine multiple conditions using the WHERE clause. For example, the following example uses two conditions:

SELECT * FROM employees WHERE DeptID=3 AND Title=’Engineer’


Sorting results

By default, a database does not sort the records returned from a SQL query. In fact, you cannot guarantee that the records returned from the same query are returned in the same order each time you run the query.

However, if you require records in a specific order, you can write your SQL statement to sort the records returned from the database. To do so, you include an ORDER BY clause in the SQL statement.

For example, the following SQL statement returns the records of the table ordered by the LastName column:

SELECT * FROM employees ORDER BY LastName

You can combine multiple fields in the ORDER BY clause to perform additional sorting:

SELECT * FROM employees ORDER BY DepartmentID, LastName

This statement returns row ordered by department, then by last name within the department.


Returning a subset of columns

You might want only a subset of columns returned from a database table, as in the following example, which returns only the FirstName, LastName, and Phone columns. This example is useful if you are building a Web page that shows the phone numbers for all employees.

SELECT FirstName, LastName, Phone FROM employees

However, this query does not to return the table rows in alphabetical order. So, you can include an ORDER clause in the SQL:

SELECT the FirstName, LastName, Phone
FROM employees
ORDER BY LastName, FirstName


Using column aliases

You might have column names that you do not want to retain in the results of your SQL statement. For example, your database is set up with a column that uses a reserved word in ColdFusion, such as EQ. In this case, you can rename the column as part of the query:

SELECT EmpID, LastName, EQ as MyEQ FROM employees

The results returned by this query contains columns named EmpID, LastName, and MyEQ.


Accessing multiple tables

In a database, you can have multiple tables containing related information. You can extract information from multiple tables as part of a query. In this case, you specify multiple table names in the SELECT statement:

SELECT LastName, FirstName, Street, City, State, Zip
FROM employees, addresses
WHERE employees.EmpID = addresses.EmpID
ORDER BY LastName, FirstName

This SELECT statement uses the EmpID field to connect the two tables. This query prefixes the EmpID column with the table name. This is necessary because each table has a column named EmpID. You must prefix a column name with its table name if the column name appears in multiple tables.

In this case, you extract LastName and FirstName information from the employees table and Street, City, State, and Zip information from the addresses table. You can use output such as this is to generate mailing addresses for an employee newsletter.

The results of a SELECT statement that references multiple tables is a single result table containing a join of the information from corresponding rows. A join means information from two or more rows is combined to form a single row of the result. In this case, the resultant record set has the following structure:

This is a picture of the feature being described.

What is interesting in this result is that even though you used the EmpID field to combine information from the two tables, you did not include that field in the output.


Modifying a database

You can use SQL to modify a database in various ways:

  • Inserting data into a database
  • Updating data in a database
  • Deleting data from a database
  • Updating multiple tables

The following sections describe these modifications.


Inserting data into a database

You use SQL INSERT statement to write information to a database. A write adds a new row to a database table. The basic syntax of an INSERT statement is:

INSERT INTO table_name(column_names)
VALUES(value_list)

where:

  • column_names specifies a comma-separated list of columns.
  • value_list specifies a comma-separated list of values. The order of values has to correspond to the order that you specified column names.

Note: There are additional options to INSERT depending on your database. For a complete syntax description for INSERT, see the product documentation.

For example, the following SQL statement adds a new row to the employees table:

INSERT INTO employees(EmpID, LastName, Firstname)
VALUES(51, 'Smith', 'John')

This statement creates a new row in the employees table and sets the values of the EmpID, LastName, and FirstName fields of the row. The remaining fields in the row are set to Null. Null means the field does not contain a value.

When you, or your database administrator, creates a table, you can set properties on the table and the columns of the table. One of the properties you can set for a column is whether the field supports Null values. If a field supports Nulls, you can omit the field from the INSERT statement. The database automatically sets the field to Null when you insert a new row.

However, if the field does not support Nulls, you must specify a value for the field as part of the INSERT statement; otherwise, the database issues an error.

The LastName and FirstName values in the query are contained within single quotes. This is necessary because the table columns are defined to contain character strings. Numeric data does not require the quotes.


Updating data in a database

Use the UPDATE statement in SQL to update the values of a table row. Update lets you update the fields of a specific row or all rows in the table. The UPDATE statement has the following syntax:

UPDATE table_name
SET column_name1=value1, ... , column_nameN=valueN
[ WHERE search_condition ]

Note: There are additional options to UPDATE depending on your database. For a complete syntax description for UPDATE, see the product documentation.

You should not attempt to update a record’s primary key field. Your database typically enforces this restriction.

The UPDATE statement uses the optional WHERE clause, much like the SELECT statement, to determine which table rows to modify. The following UPDATE statement updates the e-mail address of John Smith:

UPDATE employees SET Email='jsmith@mycompany.com' WHERE EmpID = 51

Be careful using UPDATE. If you omit the WHERE clause to execute the following statement:

UPDATE employees SET Email = 'jsmith@mycompany.com'

you update the Email field for all rows in the table.


Deleting data from a database

The DELETE statement removes rows from a table. The DELETE statement has the following syntax:

DELETE FROM table_name
[ WHERE search_condition ]

Note: There are additional options to DELETE depending on your database. For a complete syntax description for DELETE, see the product documentation.

You can remove all rows from a table using a statement in the form:

DELETE FROM employees

Typically, you specify a WHERE clause to the DELETE statement to delete specific rows of the table. For example, the following statement deletes John Smith from the table:

DELETE FROM employees WHERE EmpID=51


Updating multiple tables

The examples in this section all describe how to modify a single database table. However, you might have a database that uses multiple tables to represent information.

One way to update multiple tables is to use one INSERT statement per table and to wrap all INSERT statements within a database transaction. A transaction contains one or more SQL statements that can be rolled back or committed as a unit. If any single statement in the transaction fails, you can roll back the entire transaction, cancelling any previous writes that occurred within the transaction. You can use the same technique for updates and deletes.


Writing Queries Using an Editor

Dreamweaver MX, ColdFusion Studio, and HomeSite+ provide a GUI for writing and executing queries. A GUI is useful for developing and testing your queries before you insert them into a ColdFusion application.

This section contains a brief description of these GUIs. For more information, see the documentation on your specific tool.


Writing queries using Dreamweaver MX

This section describes how to define a query using the Dreamweaver MX Recordset dialog box, which allows you to create a record set without having to manually enter SQL statements. Defining a record set using this method can be as easy as selecting a database connection and table from the pop-up menus.

To define a record set without writing SQL:

  1. In the Dreamweaver Document window, open the page that will use the record set.
  2. Open the Data Bindings panel (Window > Data Bindings).
  3. In the Data Bindings panel, click the Plus (+) button and choose Recordset (Query) from the pop-up menu.

    4. The Simple Recordset dialog box appears.

    This is a picture of the feature being described.

  4. Complete the dialog box.
  5. Click the Test button to execute the query and ensure that it retrieves the information you intended.

    6. If you defined a filter that uses parameters input by users, the Test button displays the Test Value dialog box. Enter a value in the Test Value text box and click OK. If an instance of the record set is successfully created, a table displaying the data from your record set appears.

  6. Click OK to add the record set to the list of available content sources in the Data bindings panel.

If you prefer to write your own SQL statements, or need to create more complex queries then the Simple Recordset dialog box allows, you can define record sets using the Advanced Recordset dialog box

Creating an advanced record set by writing SQL

  1. In the Dreamweaver MX Document window, open the page that will use the record set.
  2. Choose Windows > Data Bindings to display the Data Bindings panel.
  3. In the Data Bindings panel, click the Plus (+) button and select Recordset (Query) from the pop-up menu.

    4. If the Simple Recordset dialog box appears, switch to the Advanced Recordset dialog box by clicking the Advanced button. The Advanced Recordset dialog box appears.

    This is a picture of the feature being described.

  4. Complete the dialog box.
  5. Click the Test button to execute the query and ensure that it retrieves the information you intended.

    6. If you defined a filter that uses parameters input by users, the Test button displays the Test Value dialog box. Enter a value in the Test Value text field and click OK. If an instance of the record set is successfully created, a table displaying the data from your record set appears.

  6. Click OK to add the record set to the list of available content sources in the Data Bindings panel.


Writing queries using ColdFusion Studio and HomeSite+

HomeSite+ includes the combined features of HomeSite 5 and ColdFusion Studio 5, with additional support for new ColdFusion MX tags. Both HomeSite+ and ColdFusion Studio support SQL Builder for writing queries.

SQL Builder is a powerful visual tool for building, testing, and saving SQL statements for use in application data queries. You can copy completed SQL code blocks directly into your ColdFusion applications.

To open SQL Builder:

Do one of the following:

  • Select Tools > SQL Builder from the HomeSite+ or ColdFusion Studio menu, select an RDS server, select a database from the drop-down list, and click New Query.
  • In the Database tab, select an RDS server, right-click a database name or a table, and select New Query.
  • Open the cfquery tag editor, select an RDS server, and click New Query.


The SQL Builder interface

The following figure shows the SQL Builder interface:

This is a picture of the feature being described.

The SQL Builder is divided into four sections:

Section | Use
Toolbar | Contains buttons for SQL keywords and commands.
Table pane | Provides a view of the tables in your query and allows you to create joins between tables.
Properties pane | Allows you to set the properties of the query, such as the columns that are being selected or the columns that are being updated.
SQL pane | Shows you the SQL statement as it is built. The SQL pane does not support reverse editing, so any changes you make in this pane will not be made to the query in the Properties pane or the Table pane.


Writing SQL statements

SQL Builder opens a SELECT statement by default, since this is the most common type of query. SQL Builder supports four types of SQL statements:

  • Select (default)
  • Insert
  • Update
  • Delete
Previous


Accessing and Retrieving Data

This chapter describes how to retrieve data from a database and work with query data. This chapter also shows how to use the cfquery tag to query a data source, and use the cfoutput tag to output the query results to a web page.

Contents
  • Working with dynamic data
  • Retrieving data
  • Outputting query data
  • Getting information about query results
  • Enhancing security with cfqueryparam
Next


Working with dynamic data

A web application page is different from a static web page because it can publish data dynamically. This can involve querying databases, connecting to LDAP or mail servers, and leveraging COM, DCOM, CORBA, or Java objects to retrieve, update, insert, and delete data at run time--as your users interact with pages in their browsers.

For ColdFusion developers, the term data source can refer to a number of different types of structured content accessible locally or across a network. You can query web sites, LDAP servers, POP mail servers, and documents in a variety of formats. Most commonly though, a database drives your applications, and for this discussion a data source means the entry point from ColdFusion to a database.

In this chapter, you build a query to retrieve data from the CompanyInfo data source. In Windows, this data source connects to a Microsoft Access database (company.mdb). In UNIX, this data source connects to a dBASE database. In subsequent chapters in this book, you insert and update data in this database.

To query a database, you must use:

  • ColdFusion data sources
  • The cfquery tag
  • SQL commands


Retrieving data

You can query databases to retrieve data at run time. The retrieved data, called the record set, is stored on that page as a query object. A query object is a special entity that contains the record set values, plus RecordCount, CurrentRow, and ColumnList query variables. You specify the query object’s name in the name attribute of the cfquery tag. The query object is often called simply “the query.”

Here is a simple cfquery tag:

<cfquery name = "GetSals" datasource = "CompanyInfo">
   SELECT * FROM  Employee
   ORDER BY LastName
</cfquery>

Note: The terms “record set” and “query object” are often used synonymously when discussing record sets for queries. For further information, see Using Query of Queries.

When retrieving data from a database, perform the following tasks:

  • To tell ColdFusion how to connect to a database, use the cfquery tag on a page.
  • To specify the data that you want to retrieve from the database, write SQL commands inside the cfquery block.
  • Later on the page, reference the query object and use its data values in any tag that presents data, such as cfoutput, cfgrid, cftable, cfgraph, or cftree.


The cfquery tag

The cfquery tag is one of the most frequently used CFML tags. You use it with the cfoutput tag to retrieve and reference the data returned from a query. When ColdFusion encounters a cfquery tag on a page, it does the following:

  • Connects to the specified data source.
  • Performs SQL commands that are enclosed within the block.
  • Returns result set values to the page in a query object.


The cfquery tag syntax

<cfquery name="EmpList" datasource="CompanyInfo">
   SQL code...
</cfquery>

In this example, the query code tells ColdFusion to:

  • Connect to the CompanyInfo data source (the company.mdb database).
  • Execute SQL code that you specify/
  • Store the retrieved data in the query object EmpList.

When creating queries to retrieve data, keep the following guidelines in mind:

  • You must use opening <cfquery> and ending </cfquery> tags, because the cfquery tag is a block tag.
  • Enter the query name and datasource attributes within the opening cfquery tag.
  • To tell the database what to process during the query, place SQL statements inside the cfquery block.
  • When referencing text literals in SQL, use single quotation marks ('). For example, SELECT * FROM mytable WHERE FirstName='Jacob' selects every record from mytable in which the first name is Jacob.
  • Surround attribute values with double quotation marks (“attrib_value”).
  • Make sure that a data source exists in the ColdFusion Administrator before you reference it in a cfquery tag.
  • Columns and tables that you refer to in your SQL statement must exist, otherwise the query will fail.
  • Reference the query data by naming the query in one of the presentation tags, such as cfoutput, cfgrid, cftable, cfgraph, or cftree later on the page.
  • When ColdFusion returns database columns, it removes table and owner prefixes. For example, if you query Employee.Emp_ID in the query, the Employee, is removed and returns as Emp_ID. You can use an alias to handle duplicate column names; for further information, see Using Query of Queries.
  • You cannot use SQL reserved words, such as MIN, MAX, COUNT, in a SQL statement. Because reserved words are database-dependent, see your database’s documentation for a list of reserved words.


Building queries

As discussed earlier in this chapter, you build queries using the cfquery tag and SQL.

Note: This and many subsequent procedures use the CompanyInfo data source that connects to the company.mdb database. This data source is installed by default. For information on adding or configuring a data source, see Administering ColdFusion MX.

To query the table:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Employee List</title>
</head>
<body>
<h1>Employee List</h1>
<cfquery name="EmpList" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary, Contract
   FROM Employee
</cfquery>
</body>
</html>
  2. Save the page as emplist.cfm in the myapps directory under your web_root. For example, the default path on a Windows machine would be:

    3. C:\CFusionMX\wwwroot\myapps\

  3. Enter the following URL in your web browser:

    4. http://127.0.0.1/myapps/emplist.cfm

    Only the header appears:

    This is a picture of the feature being described.

  4. View the source in the browser:

    5. This is a picture of the feature being described.

    ColdFusion creates the EmpList data set, but only HTML and text return to the browser. When you view the page’s source, you see only HTML tags and the heading “Employee List.” To display the data set on the page, you must code tags and variables to output the data.


Reviewing the code

The query you just created retrieves data from the CompanyInfo database. The following table describes the code and its function:

Code
Description
<cfquery name="EmpList"
datasource="CompanyInfo">
Queries the database specified in the CompanyInfo data source.
SELECT FirstName, LastName, Salary,
Contract
FROM Employee
Gets information from the FirstName, LastName, Salary, and Contract fields in the Employee table.
</cfquery>
Ends the cfquery block.


Outputting query data

After you define a query on a page, you can use the cfoutput tag with the query attribute to output data from the record set to a page. When you use the query attribute, keep the following in mind:

  • ColdFusion loops through all the code contained within the cfoutput block, once for each row in the record set returned from the database.
  • You must reference specific column names within the cfoutput block to output the data to the page.
  • You can place text, CFML tags, and HTML tags inside or surrounding the cfoutput block to format the data on the page.
  • Although you do not have to specify the query name when you refer to a query column, you should use the query name as a prefix for best practices reasons. For example, if you specify the Emplist query in your cfoutput tag, you can refer to the Firstname column in the Emplist query as Firstname. However, using the query name as a prefix--Emplist.Firstname-- is preferred, and is in the following procedure.

The cfoutput tag accepts a variety of optional attributes but, ordinarily, you use the query attribute to define the name of an existing query.

To output query data on your page:

  1. Edit emplist.cfm so that it appears as follows:
    2. <html>
<head>
<title>Employee List</title>
</head>
<body>
<h1>Employee List</h1>
<cfquery name="EmpList" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary, Contract
   FROM Employee
</cfquery>
<cfoutput query="EmpList">
#EmpList.FirstName#, #EmpList.LastName#, #EmpList.Salary#,
#EmpList.Contract#<br>
</cfoutput>
</body>
</html>
  2. Save the file and view it in your web browser:

    3. This is a picture of the feature being described.

    A list of employees appears in the browser, with each line displaying one row of data.

    Note: You may need to refresh your browser to see your changes.

You created a ColdFusion application page that retrieves and displays data from a database. At present, the output is raw and needs formatting. For more information, see Retrieving and Formatting Data.


Reviewing the code

The results of the query appear on the page. The following table describes the code and its function:

Code
Description
<cfoutput query="EmpList">
Displays information retrieved in the EmpList query.
#EmpList.FirstName#, #EmpList.LastName#,
#EmpList.Salary#, #EmpList.Contract#
Displays the value of the FirstName, LastName, Salary, and Contract fields of each record, separated by commas and spaces.
<br>
Inserts a line break (go to the next line) after each record.
</cfoutput>
Ends the cfoutput block.


Query output notes and considerations

When outputting query results, keep the following guidelines in mind:

  • A cfquery must precede the cfoutput that references its results. Both must be on the same page (unless you use the cfinclude tag; for more information, see Including pages with the cfinclude tag).
  • It is a good idea to place queries at the top of the page, to simplify testing and debugging. However, some queries may not execute if certain conditions are not met.
  • To output data from all the records of a query, specify the query name by using the query attribute in the cfoutput tag.
  • Columns must exist and be retrieved to the application to output their values.
  • Inside a cfoutput block that uses a cfquery attribute, you can prefix the query variables with the name of the query; for example, Emplist.FirstName.
  • As with other attributes, surround the query attribute value with double quotes (").
  • As with any variables that you reference for output, surround column names with pound signs (#) to tell ColdFusion to output the column’s current values.
  • Add a <br> tag to the end of the variable references so that ColdFusion starts a new line for each row that the query returns.


Getting information about query results

Each time you query a database with the cfquery tag, you get the data (the record set) and the query variables; together these comprise the query object. The following table describes the query variables, which are sometimes referred to as query properties:

Variable | Description
RecordCount | The total number of records returned by the query.
ColumnList | A comma-delimited list of the query columns, in alphabetical order.
CurrentRow | The current row of the query being processed by cfoutput.

In your CFML code, you can use these variables as if they were columns in a database table.

To output the query record count on your page:

  1. Edit emplist.cfm so that it appears as follows:
    2. <html>
<head>
<title>Employee List</title>
</head>
<body>
<h1>Employee List</h1>
<cfquery name="EmpList" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary, Contract
   FROM Employee
</cfquery>
<cfoutput query="EmpList">
   #EmpList.FirstName#, #EmpList.LastName#, #EmpList.Salary#,
#EmpList.Contract#<br>
</cfoutput>
<br>
<cfoutput>
   The query returned #EmpList.RecordCount# records.
</cfoutput>
</body>
</html>
  2. Save the file and view it in your web browser:

    3. This is a picture of the feature being described.

    The number of employees now appears below the list of employees. You might have to refresh your browser and scroll to see the RecordCount output.

Note: The variable cfquery.executionTime contains the amount of time, in milliseconds, it took for the query to complete. Do not prefix the variable name with the query name.


Reviewing the code

You now display the number of records retrieved in the query. The following table describes the code and its function:

Code
Description
<cfoutput>
Displays what follows.
The query returned
Displays the text “The query returned”.
#EmpList.RecordCount#
Displays the number of records retrieved in the EmpList query.
records
Displays the text “records”.
</cfoutput>
Ends the cfoutput block.


Query variable notes and considerations

When using query variables, keep the following guidelines in mind:

  • Reference the query variable within a cfoutput block so that ColdFusion outputs the query variable value to the page.
  • Surround the query variable reference with pound signs (#) so that ColdFusion knows to replace the variable name with its current value.
  • Do not use the cfoutput tag query attribute when you output the RecordCount or ColumnList property. If you do, you get one copy of the output for each row. Instead, prefix the variable with the name of the query.


Enhancing security with cfqueryparam

Some Database Management Systems (DBMSs) let you send multiple SQL statements in a single query. In many development environments--including ColdFusion, ASP, and CGI--URL or form variables in a dynamic query can append malicious SQL statements to existing queries. Be aware that there are potential security risks when you pass parameters in a query string.


About query string parameters

When you let a query string pass a parameter, ensure that only the expected information is passed. The following ColdFusion query contains a WHERE clause, which selects only database entries that match the last name specified in the LastName field of a form:

<cfquery name="GetEmployees" datasource="CompanyInfo">
  SELECT FirstName, LastName, Salary
  FROM Employee
  WHERE LastName='#Form.LastName#'
</cfquery>

Someone could call this page with the following malicious URL:

http://myserver/page.cfm?Emp_ID=7%20DELETE%20FROM%20Employee

The result is that ColdFusion tries to execute the following query:

<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT *    FROM Employee
   WHERE Emp_ID = 7 DELETE FROM Employee
</cfquery>

In addition to an expected integer for the Emp_ID column, this query also passes malicious string code in the form of a SQL statement. If this query successfully executes, it deletes all rows from the Employee table--something you definitely do not want to enable by this method. To prevent such actions, you must evaluate the contents of query string parameters.


Using cfqueryparam

You can use the cfqueryparam tag to evaluate query string parameters and pass a ColdFusion variable within a SQL statement. This tag evaluates variable values before they reach the database. You specify the data type of the corresponding database column in the cfsqltype attribute of the cfqueryparam tag. In the preceding example, because the Emp_ID column in the CompanyInfo data source is an integer, you specify a cfsqltype of cf_sql_integer:

<cfquery name="EmpList" datasource="CompanyInfo">
   SELECT *    FROM Employee
   WHERE Emp_ID = <cfqueryparam value = "#Emp_ID#"
                     cfsqltype = "cf_sql_integer">
</cfquery>

The cfqueryparam tag checks that the value of Emp_ID is an integer data type. If anything else in the query string is not an integer, such as a SQL statement to delete a table, the cfquery tag does not execute. Instead, the cfqueryparam tag returns the following error message:

Invalid data '7 DELETE FROM Employee' for CFSQLTYPE 'CF_SQL_INTEGER'.


Using cfqueryparam with strings

When passing a variable containing a string to a query, specify a cfsqltype of cf_sql_char, as in the following example:

<cfquery name = "getFirst" dataSource = "cfsnippets">
   SELECT * FROM employees
   WHERE LastName = <cfqueryparam value = "#LastName#"
                        cfsqltype = "cf_sql_char" maxLength = "17">
</cfquery>

In this case, cfqueryparam performs several checks:

  • It ensures that LastName contains a string.
  • It ensures that the string is 17 characters or less.
  • It escapes the string with single quotes so that it appears as a single value to the database. So even if you pass a bad URL, it appears as:

    • WHERE LastName = 'Anwar DELETE FROM MyCustomerTable'.


Using cfSqlType

The following table lists the available SQL types against which you can evaluate the value attribute of the cfqueryparam tag:

BIGINT | BIT | CHAR | DATE
DECIMAL | DOUBLE | FLOAT | IDSTAMP
INTEGER | LONGVARCHAR | MONEY | MONEY4
NUMERIC | REAL | REFCURSOR | SMALLINT
TIME | TIMESTAMP | TINYINT | VARCHAR
Previous


Updating Your Database

This chapter describes how to use ColdFusion to insert, update, and delete information in a database.

Contents
  • About updating your database
  • Inserting data
  • Updating data
  • Deleting data
Next


About updating your database

ColdFusion was originally developed as a way to readily interact with databases. You can quickly insert, update, and delete the contents of your database by using ColdFusion forms, which are typically a pair of pages. One page displays the form with which your end user will enter values; the other page performs the action (insert, update or delete).

Depending on the extent and type of data manipulation, you can use CFML with or without SQL commands. If you use SQL commands, ColdFusion requires a minimal amount of SQL knowledge.


Inserting data

You usually use two application pages to insert data into a database:

  • An insert form
  • An insert action page

You can create an insert form with standard HTML form tags or with cfform tags (see Creating forms with the cfform tag). When the user submits the form, form variables are passed to a ColdFusion action page that performs an insert operation (and whatever else is called for) on the specified data source. The insert action page can contain either a cfinsert tag or a cfquery tag with a SQL INSERT statement. The insert action page should also contain a confirmation message for the end user.


Creating an HTML insert form

The following procedure creates a form using standard HTML tags. The form looks like this in your web browser:

This is a picture of the feature being described.

To create an insert form:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Insert Data Form</title>
</head>

<body>
<h2>Insert Data Form</h2>

<table>
<!--- begin html form;
put action page in the "action" attribute of the form tag --->
<form action="insert_action.cfm" method="post">
<tr>
   <td>Employee ID:</td>
   <td><input type="text" name="Emp_ID" size="4" maxlength="4"></td>
</tr>
<tr>
   <td>First Name:</td>
   <td><input type="Text" name="FirstName" size="35" maxlength="50"></td>
</tr>
<tr>
   <td>Last Name:</td>
   <td><input type="Text" name="LastName" size="35" maxlength="50"></td>
</tr>
<tr>
   <td>Department Number:</td>
   <td><input type="Text" name="Dept_ID" size="4" maxlength="4"></td>
</tr>
<tr>
   <td>Start Date:</td>
   <td><input type="Text" name="StartDate" size="16" maxlength="16"></td>
</tr>
<tr>
   <td>Salary:</td>
   <td><input type="Text" name="Salary" size="10" maxlength="10"></td>
</tr>
<tr>
   <td>Contractor:</td>
   <td><input type="checkbox" name="Contract" value="Yes" checked>Yes</td>
</tr>
<tr>
   <td>&nbsp;</td>
   <td><input type="Submit" value="Submit">&nbsp;<input type="Reset"
value="Clear Form"></td>
</tr>
</form>
<!--- end html form --->
</table>

</body>
</html>
  2. Save the file as insert_form.cfm in the myapps directory under your web_root and view it in your web browser.

Note: The form will not work until you write an action page for it. For more information, see Creating an action page to insert data.


Data entry form notes and considerations

If you use the cfinsert tag in the action page to insert the data into the database, you should follow these rules for creating the form page:

  • You only need to create HTML form fields for the database columns into which you will insert data.
  • By default, cfinsert inserts all of the form’s fields into the database columns with the same names. For example, it puts the Form.Emp_ID value in the database Emp_ID column. The tag ignores form fields that lack corresponding database column names.

Note: You can also use the formfields attribute of the cfinsert tag to specify which fields to insert; for example, formfields="prod_ID,Emp_ID,status".


Creating an action page to insert data

You can use the cfinsert tag or the cfquery tag to create an action page that inserts data into a database.


Creating an insert action page with cfinsert

The cfinsert tag is the easiest way to handle simple inserts from either a cfform or an HTML form. This tag inserts data from all the form fields with names that match database field names.

To create an insert action page with cfinsert:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head> <title>Input form</title> </head>

<body>
<!--- If the Contractor check box is clear,
   set the value of the Form.Contract to "No" --->
<cfif not isdefined("Form.Contract")>
   <cfset Form.Contract = "No">
</cfif>

<!--- Insert the new record --->
<cfinsert datasource="CompanyInfo" tablename="Employee">

<h1>Employee Added</h1>
<cfoutput>You have added #Form.FirstName# #Form.Lastname# to the
         employee database.
</cfoutput>

</body>
</html>
  2. Save the page as insert_action.cfm.
  3. View insert_form.cfm in your web browser and enter values.

    4. Note: You might wish to compare views of the Employee table in the CompanyInfo data source before and after inserting values in the form.

  4. Click Submit.

    5. ColdFusion inserts your values into the Employee table and displays a confirmation message.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfif not isdefined("Form.Contract")>
   <cfset Form.Contract = "No">
</cfif>
Sets the value of Form.Contract to No if it is not defined. If the Contractor check box is unchecked, no value is passed to the action page; however, the database field must have some value.
<cfinsert datasource="CompanyInfo"
   tablename="Employee">
Creates a new row in the Employee table of the CompanyInfo database. Inserts data from the form into the database fields with the same names as the form fields.
<cfoutput>You have added
#Form.FirstName# #Form.Lastname#
to the employee database.
</cfoutput>
Informs the user that values were inserted into the database.

Note: If you use form variables in cfinsert or cfupdate tags, ColdFusion automatically validates any form data it sends to numeric, date, or time database columns. You can use the hidden field validation functions for these fields to display a custom error message. For more information, see Retrieving and Formatting Data.


Creating an insert action page with cfquery

For more complex inserts from a form submittal, you can use a SQL INSERT statement in a cfquery tag instead of using a cfinsert tag. The SQL INSERT statement is more flexible because you can insert information selectively or use functions within the statement.

The following procedure assumes that you have created the insert_action.cfm page, as described in Creating an insert action page with cfinsert.

To create an insert action page with cfquery:

  1. In insert_action.cfm, replace the cfinsert tag with the following highlighted cfquery code:
    2. <html>
<head>
   <title>Input form</title>
</head>

<body>
<!--- If the Contractor check box is clear),
   set the value of the Form.Contract to "No" --->
<cfif not isdefined("Form.Contract")>
   <cfset Form.Contract = "No">
</cfif>

<!--- Insert the new record --->
<cfquery name="AddEmployee" datasource="CompanyInfo">
   INSERT INTO Employee
   VALUES (#Form.Emp_ID#, '#Form.FirstName#',
'#Form.LastName#', #Form.Dept_ID#,
'#Form.StartDate#', #Form.Salary#, '#Form.Contract#')
</cfquery>

<h1>Employee Added</h1>
<cfoutput>You have added #Form.FirstName# #Form.Lastname# to the
         employee database.
</cfoutput>

</body>
</html>
  2. Save the page.
  3. View insert_form.cfm in your web browser and enter values.
  4. Click Submit.

    5. ColdFusion inserts your values into the Employee table and displays a confirmation message.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cfquery name="AddEmployee"
datasource="CompanyInfo">
   INSERT INTO Employee
   VALUES (#Form.Emp_ID#,
      '#Form.FirstName#',
      '#Form.LastName#',
      #Form.Dept_ID#,
      '#Form.StartDate#',
      #Form.Salary#,
      '#Form.Contract#')
</cfquery>
Inserts a new row into the Employee table of the CompanyInfo database. Specifies each form field to be added.
Because you are inserting data into all database fields in the same left-to-right order as in the database, you do not have to specify the database field names in the query.
Because #From.Emp_ID#, #Form.Dept_ID#, and #Form.Salary# are numeric, they do not need to be enclosed in quotation marks.


Inserting into specific fields

The preceding example inserts data into all the fields of a table (the Employee table has seven fields). There might be times when you do not want users to add data into all fields. To insert data into specific fields, the SQL statement in the cfquery must specify the field names following both INSERT INTO and VALUES. For example, the following cfquery omits salary and start date information from the update. Database values for these fields are 0 and NULL, respectively, according to the database’s design.

<cfquery name="AddEmployee" datasource="CompanyInfo">
   INSERT INTO Employee
      (Emp_ID,FirstName,LastName,
      Dept_ID,Contract)
   VALUES
      (#Form.Emp_ID#,'#Form.FirstName#','#Form.LastName#',
      #Form.Dept_ID#,'#Form.Contract#')
</cfquery>


Updating data

You usually use two application pages to update data in a database:

  • An update form
  • An update action page

You can create an update form with cfform tags or HTML form tags. The update form calls an update action page, which can contain either a cfupdate tag or a cfquery tag with a SQL UPDATE statement. The update action page should also contain a confirmation message for the end user.


Creating an update form

There are two key differences between an update form and an insert form:

  • An update form contains a reference to the primary key of the record that is being updated.

    • A primary key is a field(s) in a database table that uniquely identifies each record. For example, in a table of employee names and addresses, only the Emp_ID is unique to each record.

  • An update form is usually populated with existing record data.

The easiest way to designate the primary key in an update form is to include a hidden input field with the value of the primary key for the record you want to update. The hidden field indicates to ColdFusion which record to update.

To create an update form:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Update Form</title>
</head>

<body>
<cfquery name="GetRecordtoUpdate"
   datasource="CompanyInfo">
   SELECT * FROM Employee
   WHERE Emp_ID = #URL.Emp_ID#
</cfquery>

<cfoutput query="GetRecordtoUpdate">
<table>
<form action="update_action.cfm" method="Post">
   <input type="Hidden" name="Emp_ID"
      value="#Emp_ID#"><br>
<tr>
   <td>First Name:</td>
   <td><input type="text" name="FirstName" value="#FirstName#"></td>
</tr>
<tr>
   <td>Last Name:</td>
   <td><input type="text" name="LastName" value="#LastName#"></td>
</tr>
<tr>
   <td>Department Number:</td>
   <td><input type="text" name="Dept_ID" value="#Dept_ID#"></td>
</tr>
<tr>
   <td>Start Date:</td>
   <td><input type="text" name="StartDate" value="#StartDate#"></td>
</tr>
<tr>
   <td>Salary:</td>
   <td><input type="text" name="Salary" value="#Salary#"></td>
</tr>
<tr>
   <td>Contractor:</td>
   <td><cfif #Contract# IS "Yes">
      <input type="checkbox" name="Contract" checked>Yes
   <cfelse>
      <input type="checkbox" name="Contract">Yes
   </cfif></td>
</tr>
<tr>
   <td>&nbsp;</td>
   <td><input type="Submit" value="Update Information"></td>
</tr>
</form>
</table>
</cfoutput>

</body>
</html>
  2. Save the file as update_form.cfm.
  3. View update_form.cfm in your web browser by specifying the page URL and an Employee ID; for example, type the following:

    4. http://localhost/myapps/update_form.cfm?Emp_ID=3.

    Note: Although you can view an employee’s information, you must code an action page before you can update the database. For more information, see Creating an action page to update data.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfquery name="GetRecordtoUpdate"
   datasource="CompanyInfo">
   SELECT * FROM Employee
   WHERE Emp_ID = #URL.Emp_ID#
</cfquery>
Queries the CompanyInfo data source and returns records in which the employee ID matches what was entered in the URL that called this page.
<cfoutput query="GetRecordtoUpdate">
...
</cfoutput>
Makes available as variables the results of the GetRecordtoUpdate query in the form created in subsequent lines.
<form action="update_action.cfm" method="Post">
...
</form>
Creates a form whose variables will be processed on the update_action.cfm action page.
<input type="Hidden" name="Emp_ID"
   value="#Emp_ID#"><br>
Uses a hidden input field to pass the Emp_ID (primary key) value to the action page.
First Name:
<input type="text" name="FirstName"
value="#FirstName#"><br>
Last Name:
<input type="text" name="LastName"
value="#LastName#"><br>
Department Number:
<input type="text" name="Dept_ID"
      value="#Dept_ID#"><br>
Start Date:
<input type="text" name="StartDate"
value="#StartDate#"><br>
Salary:
<input type="text" name="Salary"
value="#Salary#"><br>
Populates the fields of the update form. This example does not use ColdFusion formatting functions. As a result, start dates look like 1985-03-12 00:00:00 and salaries do not have dollar signs or commas. The user can replace the information in any field using any valid input format for the data.
Contractor:
<cfif #Contract# IS "Yes">
   <input type="checkbox" name="Contract"
      checked>Yes<br>
<cfelse>
   <input type="checkbox" name="Contract">
      Yes <br>
</cfif>
<br>
<input type="Submit" value="Update Information">
</form>
</cfoutput>
The Contract field requires special treatment because a check box displays and sets its value. The cfif structure puts a check mark in the check box if the Contract field value is Yes, and leaves the box empty otherwise.


Creating an action page to update data

You can create an action page to update data with either the cfupdate tag or cfquery with the UPDATE statement.


Creating an update action page with cfupdate

The cfupdate tag is the easiest way to handle simple updates from a front-end form. The cfupdate tag has an almost identical syntax to the cfinsert tag.

To use the cfupdate tag, you must include the primary key field(s) in your form submittal. The cfupdate tag automatically detects the primary key field(s) in the table that you are updating and looks for them in the submitted form fields. ColdFusion uses the primary key field(s) to select the record to update (therefore, you cannot update the primary key value itself). It then uses the remaining form fields that you submit to update the corresponding fields in the record. Your form only needs to have fields for the database fields that you want to change.

To create an update page with cfupdate:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Update Employee</title>
</head>
<body>
<cfif not isdefined("Form.Contract")>
   <cfset form.contract = "No">
<cfelse>
   <cfset form.contract = "Yes">
</cfif>

<cfupdate datasource="CompanyInfo"
   tablename="Employee">

<h1>Employee Updated</h1>
<cfoutput>
You have updated the information for #Form.FirstName#
#Form.LastName# in the employee database.
</cfoutput>

</body>
</html>
  2. Save the page as update_action.cfm.
  3. View update_form.cfm in your web browser by specifying the page URL and an Employee ID; for example, type the following:

    4. http://localhost/myapps/update_form.cfm?Emp_ID=3.

    The current information for that record appears:

    This is a picture of the feature being described.

  4. Enter new values in any of the fields, and click Update Information.

    5. ColdFusion updates the record in the Employee table with your new values and displays a confirmation message.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfif not isdefined("Form.Contract")>
   <cfset Form.contract = "No">
<cfelse>
   <cfset form.contract = "Yes">
</cfif>
Sets the value of Form.Contract to No if it is not defined, or to Yes if it is defined. If the Contractor check box is unchecked, no value is passed to the action page; however, the database field must have some value.
<cfupdate datasource="CompanyInfo"
   tablename="Employee">
Updates the record in the database that matches the primary key on the form (Emp_ID). Updates all fields in the record with names that match the names of form controls.
<cfoutput>
You have updated the information for
   #Form.FirstName# #Form.LastName#
   in the employee database.
</cfoutput>
Informs the user that the change was made successfully.


Creating an update action page with cfquery

For more complicated updates, you can use a SQL UPDATE statement in a cfquery tag instead of a cfupdate tag. The SQL UPDATE statement is more flexible for complicated updates.

The following procedure assumes that you have created the update_action.cfm page as described in Creating an update action page with cfupdate.

To create an update page with cfquery:

  1. In update_action.cfm, replace the cfupdate tag with the following highlighted cfquery code:
    2. <html>
<head>
   <title>Update Employee</title>
</head>
<body>
<cfif not isdefined("Form.Contract")>
   <cfset form.contract = "No">
<cfelse>
   <cfset form.contract = "Yes">
</cfif>

<!--- cfquery requires date formatting when retrieving from
Access. Use the left function when setting StartDate to trim
the ".0" from the date when it first appears from the
Access database --->
 <cfquery name="UpdateEmployee" datasource="CompanyInfo">
   UPDATE Employee
   SET FirstName = '#Form.Firstname#',
      LastName = '#Form.LastName#',
      Dept_ID = #Form.Dept_ID#,
      StartDate = '#left(Form.StartDate,19)#',
      Salary = #Form.Salary#
   WHERE Emp_ID = #Form.Emp_ID#
</cfquery>

<h1>Employee Updated</h1>
<cfoutput>
You have updated the information for
#Form.FirstName# #Form.LastName#
in the employee database.
</cfoutput>
</body>
</html>
  2. Save the page.
  3. View update_form.cfm in your web browser by specifying the page URL and an Employee ID; for example, type the following:

    4. http://localhost/myapps/update_form.cfm?Emp_ID=3.

  4. Enter new values in any of the fields, and click Update Information.

    5. ColdFusion updates the record in the Employee table with your new values and displays a confirmation message.

When the cfquery tag retrieves date information from a Microsoft Access database, it displays the date with a tenths of seconds, as follows:

This is a picture of the feature being described.

This example uses the left function to trim the two final characters. The CompanyInfo data source connects to company.mdb.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cfquery name="UpdateEmployee"
   datasource="CompanyInfo">
   UPDATE Employee
   SET FirstName = '#Form.Firstname#',
      LastName = '#Form.LastName#',
      Dept_ID = #Form.Dept_ID#,
      StartDate = '#left(Form.StartDate,19)#',
      Salary = #Form.Salary#
   WHERE Emp_ID = #Form.Emp_ID#
</cfquery>
Updates the specified columns in the record in the Employee table of the CompanyInfo database that matches the primary key (Emp_ID).
Because #Form.Dept_ID#, #Form.Salary#, and #Form.Emp_ID# are numeric, they do not need to be enclosed in quotation marks.
Because of the way cfquery gets and displays dates from Access databases, you use the left function to trim the returned value.


Deleting data

You use a cfquery tag with a SQL DELETE statement to delete data from a database. ColdFusion has no cfdelete tag.


Deleting a single record

To delete a single record, use the table’s primary key in the WHERE condition of a SQL DELETE statement. In the following procedure, Emp_ID is the primary key, so the SQL Delete statement is as follows:

DELETE FROM Employee WHERE Emp_ID = #Form.Emp_ID#

You often want to see the data before you delete it. The following procedure displays the data to be deleted by reusing the form page used to insert and update data. Any data that you enter in the form before submitting it is not used, so you can use a table to display the record to be deleted instead.

To delete one record from a database:

  1. In update_form.cfm, change the title to “Delete Form” and the text on the submit button to “Delete Record”.
  2. Change the form tag so that it appears as follows:
    3. <form action="delete_action.cfm" method="Post">
  3. Save the modified file as delete_form.cfm.
  4. Create a ColdFusion page with the following content:
    5. <html>
<head>
<title>Delete Employee Record</title>
</head>
<body>

<cfquery name="DeleteEmployee"
   datasource="CompanyInfo">
      DELETE FROM Employee
      WHERE Emp_ID = #Form.Emp_ID#
</cfquery>

<h1>The employee record has been deleted.</h1>
<cfoutput>
You have deleted #Form.FirstName# #Form.LastName# from the
employee database.
</cfoutput>
</body>
</html>
  5. Save the page as delete_action.cfm.
  6. View delete_form.cfm in your web browser by specifying the page URL and an Employee ID; for example, type the following:

    7. http://localhost/myapps/delete_form.cfm?Emp_ID=3.

  7. Click Delete Record.

    8. ColdFusion deletes the record in the Employee table and displays a confirmation message.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfquery name="DeleteEmployee"
   datasource="CompanyInfo">
      DELETE FROM Employee
      WHERE Emp_ID = #Form.Emp_ID#
</cfquery>
Deletes the record in the database whose Emp_ID column matches the Emp_ID (hidden) field on the form. Since the Emp_ID is the table’s primary key, only one record is deleted.
<cfoutput>
You have deleted #Form.FirstName#
   #Form.LastName# from the
   employee database.
</cfoutput>
Informs the user that the record was deleted.


Deleting multiple records

You can use a SQL condition to delete several records. The following example deletes the records for everyone in the Sales department (which has Dept_ID number 4) from the Employee table:

DELETE FROM Employee
WHERE Dept_ID = 4

To delete all the records from the Employee table, use the following code:

DELETE FROM Employee

Caution:Deleting records from a database is not reversible. Use DELETE statements carefully.
Previous


Using Query of Queries

A query that retrieves data from a record set is called a Query of Queries. After you generate a record set, you can interact with its results as if they were database tables by using Query of Queries. This chapter describes the benefits and procedures for this feature.

Contents
  • About record sets
  • About Query of Queries
  • Query of Queries user guide
  • BNF for Query of Queries
Next


About record sets

Query of Queries is based on manipulating the record set, which you can create using the cfquery tag and other ways.

When you execute a database query, ColdFusion retrieves the data in a record set. In addition to presenting record set data to the user, you can manipulate this record set to improve your application’s performance.

Because a record set contains rows (records) and columns (fields), you can think of it as a virtual database table, or as a spreadsheet. For example, the cfpop tag retrieves a record set in which each row is a message and each column is a message component, such as To, From, and Subject.


Referencing queries as objects

You can reference ColdFusion queries as objects by assigning a query to a variable, as follows:

<cfquery name = "query01"
  datasource = "myDNS"
  SELECT * FROM CUSTOMERS
</cfquery>
...
<cfset query02 = query01>

The query is not copied; both names point to the same record set data. Therefore, if you make changes to the table referenced in query01, the original query and the query object called query02 both reflect these changes. If you perform a copy with an array, the array is copied.


Creating a record set

You can perform a Query of Queries on any ColdFusion tag or function that generates a record set, including the following:

  • cfcollection
  • cfdirectory
  • cfftp
  • cfhttp
  • cfindex
  • cfldap
  • cfmail
  • cfpop
  • cfprocresult
  • cfquery (against a database or against another Query of Queries)
  • cfsearch
  • cfstoredproc
  • cfwddx
  • the queryNew( ); query function


Creating a record set with a function

In addition to creating a record set by using a cfquery or other CFML tags, you can create it with the queryNew() function, as follows:

To create a record set with the queryNew() function:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>The queryNew function</title>
</head>

<body>
<h2>QueryNew Example</h2>

<!--- create a query ---><cfset qInstruments = queryNew("name, instrument,
years_playing")>

<!--- add rows --->
<cfset newrow  = queryaddrow(qInstruments, 3)>

<!--- set values in cells --->
<cfset temp = querysetcell(qInstruments, "name", "Thor", 1)>
<cfset temp = querysetcell(qInstruments, "instrument", "hammer", 1)>
<cfset temp = querysetcell(qInstruments, "years_playing", "1000", 1)>

<cfset temp = querysetcell(qInstruments, "name", "Bjorn", 2)>
<cfset temp = querysetcell(qInstruments, "instrument", "sitar", 2)>
<cfset temp = querysetcell(qInstruments, "years_playing", "24", 2)>

<cfset temp = querysetcell(qInstruments, "name", "Raoul", 3)>
<cfset temp = querysetcell(qInstruments, "instrument", "flute", 3)>
<cfset temp = querysetcell(qInstruments, "years_playing", "12", 3)>

<!--- output the query --->
<cfoutput query="qInstruments">
   <pre>#name#   #instrument# #years_playing#</pre>
</cfoutput>

<h3>Individual record retrieval:</h3>
<cfoutput>
<p>#qInstruments.name[2]# has played #qInstruments.instrument[2]# for
#qInstruments.years_playing[2]# years.
</cfoutput>

</body>
</html>
  2. Save the page as queryNew.cfm in the myapps directory under the web_root.
  3. In your browser, enter the following URL to display the query results:

    4. http://127.0.0.1/myapps/queryNew.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.

Note: When you create a record set, you can store in it complex objects, such as arrays and structures. However, you cannot use Query Of Queries on a record set that contains complex objects. For more information on Query of Queries, see About Query of Queries.


About Query of Queries

After you have created a record set with a tag or function, you can query the record set in several dependent queries. A query that retrieves data from a record set is called a Query of Queries. A typical use of a Query of Queries is to retrieve an entire table into memory with one query, and then access the table data (the record set) with subsequent sorting or filtering queries. In essence, you query the record set as if it were a database table.

Note: Because you can generate a record set in ways other than using the cfquery tag, the term In Memory Query is sometimes used instead of Query of Queries.


Benefits of Query of Queries

Performing a Query of Queries has many benefits, including the following:

  • If you need to access the same tables multiple times, you greatly reduce access time, because the data is already in memory (in the record set).

    • A Query of Queries is ideal for tables of 5,000 to 50,000 rows, and is limited only by the memory of the ColdFusion Server host machine.

  • You can perform joins and union operations on results from different data sources.

    • For example, you can perform a union operation on queries from different databases to eliminate duplicates for a mailing list.

  • You can efficiently manipulate cached query results in different ways. You can query a database once, and then use the results to generate several different summary tables.

    • For example, if you need to summarize the total salary by department, by skill, and by job, you can make one query to the database and use its results in three separate queries to generate the summaries.

  • You can obtain drill-down, master-detail information for which you do not access the database for the details.

    • For example, you can select information about departments and employees in a query, and cache the results. You can then display the employees’ names. When users select an employee, the application displays the employee’s details by selecting information from the cached query, without accessing the database.


Performing a Query of Queries

There are four steps to perform a Query of Queries.

To perform a Query of Queries:

  1. Generate a record set.

    2. You can write a normal query using a tag or function that creates a record set. This is sometimes called a master query. For more information, see Creating a record set.

  2. Write a detail query--a query that specifies dbtype="query" in its cfquery tag.
  3. In the detail query, write a SQL statement that retrieves the relevant records. Specify the names of one or more existing queries as the table names in your SQL code. Do not specify a datasource attribute.
  4. If the database content does not change rapidly, use the cachedwithin attribute of the master query to cache the query results between page requests. This way, ColdFusion accesses the database on the first page request, and does not query the database again until the specified time expires. You must use the CreateTimeSpan function to specify the cachedwithin attribute value (in days, hours, minutes, seconds format).

The detail query generates a new query results set, identified by the value of the name attribute of the detail query. The following example illustrates the use of a master query and a single detail query that extracts information from the master.

To use the results of a query in a query:

  1. Create a ColdFusion page with the following content:
    2. <body>
<h1>Employee List</h1>
<!--- LastNameSearch (normally generated interactively) --->
<cfset LastNameSearch="Doe">

<!--- Master Query --->
<cfquery datasource="CompanyInfo" name="master"
   cachedwithin=#CreateTimeSpan(0,1,0,0)#>
   SELECT * from Employee
</cfquery>

<!--- Detail Query (dbtype=query, no data source) --->
<cfquery dbtype="query" name="detail">
   SELECT Emp_ID, FirstName, LastName
   FROM master
   WHERE LastName=<cfqueryparam value="#LastNameSearch#"
cfsqltype="cf_sql_char" maxLength="20"></cfquery>

<!--- output the detail query results --->
<p>Output using a query of query:</p>
<cfoutput query=detail>
   #Emp_ID#: #FirstName# #LastName#<br>
</cfoutput>
<br>

<p>Columns in the master query:</p>
<cfoutput>
   #master.columnlist#<br>
</cfoutput>
<br>

<p>Columns in the detail query:</p>
<cfoutput>
   #detail.columnlist#<br>
</cfoutput>
</body>
  2. Save the page as query_of_query.cfm in the myapps directory under the web_root.
  3. In your browser, enter the following URL to display the queryresults:

    4. http://127.0.0.1/myapps/query_of_query.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.


Reviewing the code

The master query retrieves the entire Employee table from the CompanyInfo data source (the CompanyInfo database). The detail query selects only the three columns to display for employees with the specified last name. The following table describes the code and its function:

Code
Description
cfset LastNameSearch="Doe"
Sets the last name to use in the detail query. In a complete application, this information comes from user interaction.
<cfquery datasource="CompanyInfo" name="master"
   cachedwithin=#CreateTimeSpan(0,1,0,0)#>
   SELECT *    from Employee
</cfquery>
Queries the CompanyInfo data source and selects all data in the Employees table. Caches the query data between requests to this page, and does not query the database if the cached data is less than an hour old.
<cfquery dbtype="query" name="detail">
   SELECT Emp_ID, FirstName, LastName
   FROM master
   WHERE LastName=<cfqueryparam
   value=”#LastNameSearch#"
   cfsqltype=”cf_sql_char”
   maxLength="20"></cfquery>
Uses the master query as the source of the data in a new query, named detail. This new query selects only entries that match the last name specified by the LastNameSearch variable. The query also selects only three columns of data: employee ID, first name, and last name. The query uses the cfqueryparam tag to prevent passing erroneous or harmful code.
<cfoutput query=detail>
   #Emp_ID#: #FirstName# #LastName# <br>
</cfoutput>
Uses the detail query to display the list of employee IDs, first names, and last names.
<cfoutput>
   #master.columnlist#<br>
</cfoutput>
Lists all the columns returned by the master query.
<cfoutput>
   #detail.columnlist#<br>
</cfoutput>
Lists all the columns returned by the detail query.


Displaying record set data incrementally

If your database is large, you can limit the number of rows displayed at one time. The following example shows how to use the currentRow query variable of a Query of Queries to do this. For more information on query variables, see Getting information about query results.

To display record set data incrementally:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>QoQ with incremental row return</title>
</head>

<body>
<h3>QoQ with incremental row return</h3>
<!--- define startrow and maxrows to facilitate 'next N' style browsing --->
<cfparam name = "MaxRows" default = "5">
<cfparam name = "StartRow" default = "1">

<!--- master query: retrieve all info from Employee table --->
<cfquery name = "GetSals" datasource = "CompanyInfo">
   SELECT * FROM  Employee
   ORDER BY LastName
</cfquery>

<!--- detail query: select 3 fields from the master query --->
<cfquery name = "GetSals2" dbtype = "query">
   SELECT   FirstName, LastName, Salary
   FROM     GetSals
   ORDER BY LastName
</cfquery>

<!--- build table to display output --->
<table cellpadding = 1 cellspacing = 1>
   <tr>
     <td bgcolor = f0f0f0>
     <b><i>&nbsp;</i></b>
     </td>

     <td bgcolor = f0f0f0>
     <b><i>FirstName</i></b>
     </td>

     <td bgcolor = f0f0f0>
     <b><i>LastName</i></b>
     </td>

     <td bgcolor = f0f0f0>
     <b><i>Salary</i></b>
     </td>
   </tr>

<!--- Output the query and define the startrow and maxrows
      parameters. Use the query variable currentRow to
      keep track of the row you are displaying. --->
   <cfoutput query = "GetSals2" startrow = "#StartRow#" maxrows = "#MaxRows#">
   <tr>
     <td valign = top bgcolor = ffffed>
        <b>#GetSals2.currentRow#</b>
     </td>

     <td valign = top>
        <font size = "-1">#FirstName#</font>
     </td>

     <td valign = top>
        <font size = "-1">#LastName#</font>
     </td>

     <td valign = top>
        <font size = "-1">#Salary#</font>
     </td>
   </tr>
   </cfoutput>
<!--- If the total number of records is less than or equal to
   the total number of rows, provide a link to the same page, with the
   StartRow value incremented by MaxRows (5, in this example) --->
   <tr>
     <td colspan = 4>
     <cfif (startrow + maxrows) lte getsals2.recordcount>
       <a href="qoq_next_row.cfm?startrow=<cfoutput>#Evaluate(StartRow +
MaxRows)#</cfoutput>">See next <cfoutput>#MaxRows#</cfoutput>
       rows</a>
     </cfif>
     </td>
   </tr>
</table>
</body>
</html>
  2. Save the page as qoq_next_row.cfm in the myapps directory under the web_root.
  3. In your web browser, enter the following URL to display the query results:

    4. http://127.0.0.1/myapps/qoq_next_row.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.


Using the cfdump tag with query results

As you debug your CFML code, you can use the cfdump tag to quickly present the value of your query. This tag has the following format:

<cfdump var="#query_name#">

For more information on the cfdump tag, see CFML Reference.


Using Query of Queries with non-SQL record sets

A Query of Queries can operate on any CFML tag or function that returns a record set; you are not limited to operating on cfquery results. You can perform queries on non-SQL record sets, such as a cfdirectory tag, Verity searches, a cfldap tag, and so on.

The following example shows how a Query of Queries interacts with the record set of a Verity search. This example assumes that you have a valid Verity collection, called bbb, which contains documents with a target word, film, or its variants (films, filmed, filming). Change the name of the collection and the search criteria to as appropriate for your Verity collection. For more information on Verity, see Building a Search Interface.

To use Query of Queries with a Verity record set:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>QoQ and Verity</title>
</head>

<body>
<!--- master query: retrieve all documents from the bbb collection
that contain ’film’ (or its stemmed variants); change values for
collection and criteria as needed for your Verity collection --->
<cfsearch name = "quick"
   collection="bbb"
   type = "simple"
   criteria="film">

<h3>Master query dump:</h3>
<cfdump var="#quick#">

<!--- detail query: retrieve from the master query only those
documents with a score greater than a criterion (here,
0.7743) --->
<cfquery name="qoq" dbtype="query">
   SELECT * from quick
   WHERE quick.score > 0.7743
</cfquery>

<h3>Detail query dump:</h3>
<cfdump var="#qoq#">

</body>
</html>
  2. Save the page as qoq_verity.cfm in the myapps directory under the web_root.
  3. In your web browser, enter the following URL to display the query results:

    4. http://127.0.0.1/myapps/qoq_verity.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.

    Note: This figure shows a collapsed master query output and an expanded detail query output. Click an output to expand or collapse it.

    The first cfdump tag shows the master query, which retrieves all records. The second cfdump shows the Query of Queries results.

    Tip: Adjust the score criterion of the detail query to reflect the contents of your collection.

The next example shows how a Query of Queries combines record sets from a cfdirectory tag, which is limited to retrieval of one file type per use.

To use Query of Queries to combine record sets:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Images Folder</title>
</head>

<body>
<h2>Image Retrieval with QoQ</h2>
<!--- set the images directory --->
<cfset dir = ("C:\pix\")>

<!--- retrieve all GIFs --->
<cfdirectory name="GetGIF"
  action="list"
  directory="#dir#"
  filter="*.gif">

<!--- retrieve all JPGs --->
<cfdirectory name="GetJPG"
  action="list"
  directory="#dir#"
  filter="*.jpg">

<!--- join the queries with a UNION in a QoQ (cfdirectory
         automatically returns the directory name as "Name") --->
<cfquery dbtype="query" name="GetBoth">
  SELECT * FROM GetGIF
  UNION
  SELECT * FROM GetJPG
  ORDER BY Name
</cfquery>

<!--- display output in a linked, ordered list --->
<cfoutput>
  <p>The <strong>#dir#</strong> directory contains #GetBoth.RecordCount#
images:<br>
  <ol>
    <cfloop query="GetBoth">
      <li><a href="../images/#Name#">#GetBoth.Name#</a><br>
    </cfloop>
  </ol>
</cfoutput>

</body>
</html>
  2. Save the page as qoq_cfdirectory.cfm in the myapps directory under the web_root.
  3. In your web browser, enter the following URL to display the query results:

    4. http://127.0.0.1/myapps/qoq_cfdirectory.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.


Query of Queries user guide

The following sections discuss Query of Queries functionality. If you know SQL or have interacted with databases, you might be familiar with some of these features.


Using dot notation

ColdFusion supports using dot notation in table names.


Example

If a structure named A contains a field named B, which contains a table named Products, you can refer to the table with dot notation, as follows:

SELECT tape_ID, length
FROM A.B.Products;


Using joins

A join operation uses a single SELECT statement to return a result set from multiple tables. The re are two main types of JOIN operations:

  • INNER JOIN includes in the result set only records that are present in both tables
  • OUTER JOIN includes in the result set all records in one of the tables.

ColdFusion does not support OUTER JOINs, nor does it support the INNER JOIN syntax, as the following example shows:

SELECT Dog_ID, Breed_ID,
FROM Dogs INNER JOIN Breed
ON Dogs.Dog_ID = Breed.Dog_ID;

ColdFusion supports INNER JOINs between two tables, as the following example shows. This operation is the most common type of join.

SELECT Dog_ID, Breed_ID
FROM Dogs, Breed
WHERE Dogs.Dog_ID = Breed.Dog_ID;


Using unions

The UNION operator lets you combine the results of two or more SELECT expressions into a single record set. The original tables must have the same number of columns, and corresponding columns must be UNION-compatible data types. Columns are UNION-compatible data types if they meet one of the following conditions:

  • The same data type; for example, both Tinyint
  • Both Numeric; for example, Tinyint, Smallint, Integer, Bigint, Double, Float, Real, Decimal, or Numeric
  • Both Characters; for example, Char, Varchar, or LongVarchar
  • Both Dates; for example, Time, TimeStamp, or Date

Note: Query Of Queries does not support ODBC-formatted dates and times.


Syntax

select_expression = select_expression UNION [ALL] select_expression


Example

This example uses the following tables:

Table1
Type(int) | Name(varchar)
1 | Tennis
2 | Baseball
3 | Football

Table2
ID(int) | Sport(varchar)
3 | Football
4 | Volleyball
5 | PingPong

To combine Table1 and Table2, use a UNION statement, as follows:

SELECT * FROM Table1
UNION
SELECT * FROM Table2

The UNION statement produces the following result (UNION) table:

Result table
Type(int) | Name(varchar)
1 | Tennis
2 | Baseball
3 | Football
4 | Volleyball
5 | PingPong


Using aliases for column names

The column names of a UNION table are the column names in the result set of the first SELECT statement in the UNION operation; ColdFusion ignores the column names in the other SELECT statement. To change the column names of the result table, you can use an alias, as follows:

Select Type as SportType, Name as SportName from Table1
UNION
Select * from Table2


Duplicate rows and multiple tables

By default, the UNION operator removes duplicate rows from the result table. If you use the keyword ALL, then duplicates are included.

You can combine an unlimited number of tables using the UNION operator, for example:

Select * from Table1
UNION
Select * from Table2
UNION
Select * from Table3
...


Parentheses and evaluation order

By default, the Query of Queries SQL engine evaluates a statement containing UNION operators from left to right. You can use parentheses to change the order of evaluation. For example, the following two statements are different:

/* First statement. */
SELECT * FROM TableA
UNION ALL
(SELECT * FROM TableB
UNION
SELECT * FROM TableC
)

/* Second statement. */
(SELECT * FROM TableA
UNION ALL
SELECT * FROM TableB
)
UNION
SELECT * FROM TableC

In the first statement, there are no duplicates in the union between TableB and TableC. Then, in the union between that set and TableA, the ALL keyword includes the duplicates. In the second statement, duplicates are included in the union between TableA and TableB but are eliminated in the subsequent union with TableC. The ALL keyword has no effect on the final result of this expression.


Using other keywords with UNION

When you perform a UNION, the individual SELECT statements cannot have their own ORDER BY or COMPUTE clauses. You can only have one ORDER BY or COMPUTE clause after the last SELECT statement; this clause is applied to the final, combined result set. You can only specify GROUP BY and HAVING expressions in the individual SELECT statements.


Using conditional operators

ColdFusion lets you use the following conditional operators in your SQL statements:

  • Test
  • Null
  • Comparison
  • Between
  • IN
  • LIKE


Test Conditional

This conditional tests whether a Boolean expression is true, false, or unknown.


Syntax


cond_test ::= expression [IS [NOT] {TRUE | FALSE | UNKNOWN} ]


Example

SELECT _isValid FROM Chemicals
WHERE _isValid IS true;


Null Conditional

This conditional tests whether an expression is null.


Syntax

null_cond ::= expression IS [NOT] NULL


Example

SELECT bloodVal FROM Standards
WHERE bloodVal IS NOT null;


Comparison Conditional

This conditional lets you compare an expression against another expression of the same data type (Numeric, String, Date, or Boolean). You can use it to selectively retrieve only the relevant rows of a record set.


Syntax

comparison_cond ::= expression [> | >= | <> | != | < | <=] expression


Example

The following example uses a comparison conditional to retrieve only those dogs whose IQ is at least 150:

SELECT dog_name, dog_IQ
FROM Dogs
WHERE dog_IQ >= 150;


Between Conditional

This conditional lets you compare an expression against another expression. You can use it to selectively retrieve only the relevant rows of a record set. Like the comparison conditional, the BETWEEN conditional makes a comparison; however, the between conditional makes a comparison against a range of values. Therefore, its syntax requires two values, which are inclusive, a minimum and a maximum. You must separate these values with the AND keyword.


Syntax

between_cond ::= expression [NOT] BETWEEN expression AND expression


Example

The following example uses a BETWEEN conditional to retrieve only those dogs whose IQ is between 150 and 165, inclusive:

SELECT dog_name, dog_IQ
FROM Dogs
WHERE dog_IQ BETWEEN 150 AND 165;


IN Conditional

This conditional lets you specify a comma-delimited list of conditions to match. It is similar in function to the OR conditional. In addition to being more legible when working with long lists, the IN conditional can contain another SELECT statement.


Syntax

in_cond ::= expression [NOT] IN (expression_list)


Example

The following example uses the IN conditional to retrieve only those dogs who were born at either Ken’s Kennels or Barb’s Breeders:

SELECT dog_name, dog_IQ, Kennel_ID
FROM Dogs
WHERE kennel_ID IN ('Kens','Barbs');


LIKE Conditional

This conditional lets you perform wildcard searches, in which you compare your data to search patterns. This strategy differs from other conditionals, such as BETWEEN or IN, because the LIKE conditional compares your data to a value that is partially unknown.


Syntax

like_cond ::= left_string_exp [NOT] LIKE right_string_exp [ESCAPE escape_char]

The left_string_exp can be either a constant string, or a column reference to a string column. The right_string_exp can be either a column reference to a string column, or a search pattern. A search pattern is a search condition that consists of literal text and at least one wildcard character. A wildcard character is a special character that represents an unknown part of a search pattern, and is interpreted as follows:

  • The underscore (_) represents any single character.
  • The percent sign (%) represents zero or more characters.
  • Square brackets ([ ]) represents any character in the range.
  • Square brackets with a caret [^] represent any character not in the range.
  • All other characters represent themselves.

Note: Earlier versions of ColdFusion do not support bracketed ranges.


Examples

The following example uses the LIKE conditional to retrieve only those dogs of the breed Terrier, whether the dog is a Boston Terrier, Jack Russell Terrier, Scottish Terrier, and so on:

SELECT dog_name, dog_IQ, breed
FROM Dogs
WHERE breed LIKE '%Terrier';

The following examples are select statements that use bracketed ranges:

SELECT lname FROM Suspects WHERE lname LIKE 'A[^c]%';
SELECT lname FROM Suspects WHERE lname LIKE '[a-m]%';
SELECT lname FROM Suspects WHERE lname LIKE '%[]';
SELECT lname FROM Suspects WHERE lname LIKE 'A[%]%';
SELECT lname FROM Suspects WHERE lname LIKE 'A[^c-f]%';


Case sensitivity

ColdFusion supports two string functions UPPER() and LOWER(), which you can use to achieve case-insensitive matching.


Examples

The following example matches only 'Sylvester':

SELECT dog_name
FROM Dogs
WHERE dog_name LIKE 'Sylvester';

The following example is not case-sensitive; it uses the LOWER() function to match 'Sylvester', 'sylvester', 'SYLVESTER', and so on:

SELECT dog_name
FROM Dogs
WHERE LOWER(dog_name) LIKE 'Sylvester';


Escaping wildcards

You can specify your own escape character using the conditional ESCAPE clause.


Example

The following example uses the ESCAPE clause to enable a search for a literal percent sign (%), which ColdFusion normally interprets as a wildcard character:

SELECT emp_discount
FROM Benefits
WHERE emp_discount LIKE '10\%'
ESCAPE '\';


Using aggregate functions

Aggregate functions operate on a set of data and return a single value. Use these functions for retrieving summary information from a table, as opposed to retrieving an entire table and then operating on the record set of the entire table.

Consider using aggregate functions to perform the following operations:

  • To display the average of a column
  • To count the number of rows for a column
  • To find the earliest date in a column

Since not every relational database management system (RDBMS) supports all aggregate functions, refer to your database’s documentation. The following table lists the aggregate functions that ColdFusion supports:

Function
Description
AVG()
Returns the average (mean) for a column.
COUNT()
Returns the number of rows in a column.
MAX()
Returns the largest value of a column.
MIN()
Returns the lowest value of a column.
SUM()
Returns the sum of values of a column.

Note: For more information, see CFML Reference.


Syntax

aggregate_func ::= <COUNT>(* | column_name) | AVG | SUM | MIN | MAX)
([ALL | DISTINCT] numeric_exp)


Example

The following example uses the AVG() function to retrieve the average IQ of all terriers:

SELECT dog_name, AVG(dog_IQ) AS avg_IQ
FROM Dogs
WHERE breed LIKE '%Terrier';


Arbitrary expressions in aggregate functions

ColdFusion supports aggregate functions of any arbitrary expression, as follows:

SELECT lorange, count(lorange+hirange)
FROM roysched
GROUP BY lorange;


Aggregate functions in arbitrary expressions

ColdFusion supports mathematical expressions that include aggregate functions, as follows:

SELECT MIN(lorange) + MAX(hirange)
FROM roysched
GROUP BY lorange;


Using group by and having expressions

ColdFusion supports the use of any arbitrary arithmetic expression, as long as it is referenced by an alias.


Examples

The following code is correct:

SELECT (lorange + hirange)/2 AS midrange,
COUNT(*)
FROM roysched
GROUP BY midrange;

The following code is correct:

SELECT (lorange+hirange)/2 AS x,
COUNT(*)
FROM    roysched GROUP BY x
HAVING x > 10000;

The following code is not supported in Query of Queries:

SELECT (lorange + hirange)/2 AS midrange,
COUNT(*)
FROM roysched
GROUP BY (lorange + hirange)/2;


Using ORDER BY clauses

ColdFusion supports the ORDER BY clause to sort. Make sure that it is the last clause in your SELECT statement. You can sort by multiple columns, by relative column position, by nonselected columns. You can specify a descending sort direction with the DESC keyword (by default, most RDBMS sorts are ascending, which makes the ASC keyword unnecessary).


Syntax

order_by_column ::= ( <IDENTIFIER> | <INTEGER_LITERAL> ) [<ASC> | <DESC>]


Examples

The following example shows a simple sort using an ORDER BY clause:

SELECT acetylcholine_levels, dopamine_levels
FROM results
ORDER BY dopamine_levels

The following example shows a more complex sort; results are first sorted by ascending levels of dopamine, then by descending levels of acetylcholine. The ASC keyword is unnecessary, and is used only for legibility.

SELECT acetylcholine_levels, dopamine_levels
FROM results
ORDER BY 2 ASC, 1 DESC


Using aliases

ColdFusion supports the use of database column aliases. An alias is an alternate name for a database field or value. ColdFusion lets you reuse an alias in the same SQL statement.

One way to create an alias is to concatenate (append) two or more columns to generate a value. For example, you can concatenate a first name and a last name to create the value fullname. Because the new value does not exist in a database, you refer to it by its alias. The AS keyword assigns the alias in the SELECT statement.


Examples

ColdFusion supports alias substitutions in the ORDER BY, GROUP BY, and HAVING clauses.

Note: ColdFusion does not support aliases for table names.

SELECT FirstName + ' ' + LastName AS fullname
from Employee;

The following examples rely on these two master queries:

<cfquery name="employee" datasource="2pubs">
   SELECT * FROM employee
</cfquery>

<cfquery name="roysched" datasource="2pubs">
   SELECT * FROM roysched
</cfquery>

To generate output for the following examples, use the cfdump tag. For example, use <cfdump var="#order_by#"> for the following ORDER BY example.


ORDER BY Example

<cfquery name="order_by" dbtype="query">
   SELECT (job_id + job_lvl)/2 AS job_value
   FROM employee
   ORDER BY job_value
</cfquery>


GROUP BY Example

<cfquery name="group_by" dbtype="query">
   SELECT       lorange+hirange AS x, count(hirange)
   FROM       roysched
   GROUP BY    x
</cfquery>


HAVING Example

<cfquery name="having" dbtype="query">
   SELECT (lorange+hirange)/2 AS x,
   COUNT(*)
   FROM    roysched GROUP BY x
   HAVING x > 10000
</cfquery>


Handling null values

ColdFusion uses Boolean logic to handle conditional expressions. Proper handling of NULL values requires the use of ternary logic. The IS [NOT] NULL clause works correctly in ColdFusion. However the following expressions do not work properly when the column breed is NULL:

WHERE (breed > 'A')
WHERE NOT (breed > 'A')

The correct behavior should not include NULL breed columns in the result set of either expression. To avoid this limitation, you can add an explicit rule to the conditionals and rewrite them in the following forms:

WHERE breed IS NOT NULL AND (breed > 'A')
WHERE breed IS NOT NULL AND not (breed > 'A')


Escaping reserved keywords

ColdFusion has a list of reserved keywords, which are typically part of the SQL language and are not normally used for names of columns or tables. To escape a reserved keyword for a column name or table name, enclose it in brackets.

Caution:Earlier versions of ColdFusion let you use some reserved keywords without escaping them.


Examples

ColdFusion supports the following SELECT statement examples:

SELECT [from] FROM parts;
SELECT [group].firstname FROM [group];
SELECT [group].[from] FROM [group];

ColdFusion does not support nested escapes, such as in the following example:

SELECT [[from]] FROM T;

The following table lists ColdFusion reserved keywords:

ABSOLUTE

ACTION

ADD

ALL

ALLOCATE

ALTER

AND

ANY

ARE

AS

ASC

ASSERTION

AT

AUTHORIZATION

AVG

BEGIN

BETWEEN

BIT

BIT_LENGTH

BOTH

BY

CASCADE

CASCADED

CASE

CAST

CATALOG

CHAR

CHARACTER

CHARACTER_LENGTH

CHAR_LENGTH

CHECK

CLOSE

COALESCE

COLLATE

COLLATION

COLUMN

COMMIT

CONNECT

CONNECTION

CONSTRAINT

CONSTRAINTS

CONTINUE

CONVERT

CORRESPONDING

COUNT

CREATE

CROSS

CURRENT

CURRENT_DATE

CURRENT_TIME

CURRENT_TIMESTAMP

CURRENT_USER

CURSOR

DATE

DAY

DEALLOCATE

DEC

DECIMAL

DECLARE

DEFAULT

DEFERRABLE

DEFERRED

DELETE

DESC

DESCRIBE

DESCRIPTOR

DIAGNOSTICS

DISCONNECT

DISTINCT

DOMAIN

DOUBLE

DROP

ELSE

END

END-EXEC

ESCAPE

EXCEPT

EXCEPTION

EXEC

EXECUTE

EXISTS

EXTERNAL

EXTRACT

FALSE

FETCH

FIRST

FLOAT

FOR

FOREIGN

FOUND

FROM

FULL

GET

GLOBAL

GO

GOTO

GRANT

GROUP

HAVING

HOUR

IDENTITY

IMMEDIATE

IN

INDICATOR

INITIALLY

INNER

INPUT

INSENSITIVE

INSERT

INT

INTEGER

INTERSECT

INTERVAL

INTO

IS

ISOLATION

JOIN

KEY

LANGUAGE

LAST

LEADING

LEFT

LEVEL

LIKE

LOCAL

LOWER

MATCH

MAX

MIN

MINUTE

MODULE

MONTH

NAMES

NATIONAL

NATURAL

NCHAR

NEXT

NO

NOT

NULL

NULLIF

NUMERIC

OCTET_LENGTH

OF

ON

ONLY

OPEN

OPTION

OR

ORDER

OUTER

OUTPUT

OVERLAPS

PAD

PARTIAL

POSITION

PRECISION

PREPARE

PRESERVE

PRIMARY

PRIOR

PRIVILEGES

PROCEDURE

PUBLIC

READ

REAL

REFERENCES

RELATIVE

RESTRICT

REVOKE

RIGHT

ROLLBACK

ROWS

SCHEMA

SCROLL

SECOND

SECTION

SELECT

SESSION

SESSION_USER

SET

SIZE

SMALLINT

SOME

SPACE

SQL

SQLCODE

SQLERROR

SQLSTATE

SUBSTRING

SUM

SYSTEM_USER

TABLE

TEMPORARY

THEN

TIME

TIMESTAMP

TIMEZONE_HOUR

TIMEZONE_MINUTE

TO

TRAILING

TRANSACTION

TRANSLATE

TRANSLATION

TRIM

TRUE

UNION

UNIQUE

UNKNOWN

UPDATE

UPPER

USAGE

USER

USING

VALUE

VALUES

VARCHAR

VARYING

VIEW

WHEN

WHENEVER

WHERE

WITH

WORK

WRITE

YEAR

ZONE


BNF for Query of Queries

The Backus Naur Form (BNF) is a formal notation to describe programming syntax. The following is the BNF for Query of Queries:

Input ::= select_statement

select_statement ::= select_expression ( <ORDER> <BY> order_by_list )?

select_expression ::= ( <OPENPAREN> select_expression <CLOSEPAREN> |
      select_specification ) ( <UNION> ( <ALL> )? select_expression )?

select_specification ::= <SELECT> ( <ALL> | <DISTINCT> )? select_list <FROM>
      from_table_list ( <WHERE> cond_exp )? ( <GROUP> <BY> group_by_list )?
      ( <HAVING> cond_exp )?

order_by_list ::= order_by_column ( <COMMA> order_by_column )*

order_by_column ::= ( <IDENTIFIER> | <INTEGER_LITERAL> ) ( <ASC> | <DESC> )?

group_by_list ::= column_ref ( <COMMA> column_ref )*

from_table_list ::= <IDENTIFIER> ( <COMMA> <IDENTIFIER> )*

select_list ::= select_column ( <COMMA> select_column )*

select_column ::= <ASTERISK>
 | <IDENTIFIER> <DOT> ( <ASTERISK> | <IDENTIFIER> ( alias )? )
 | expression ( alias )?

alias ::= ( <AS> )? <IDENTIFIER>

cond_exp ::= cond_term ( <OR> cond_exp )?

cond_term ::= cond_factor ( <AND> cond_term )?

cond_factor ::= ( <NOT> )? cond_test

cond_test ::= cond_primary ( <IS> ( <NOT> )? ( <TRUE> | <FALSE> | <UNKNOWN> ) )?

cond_primary ::= simple_cond
 | <OPENPAREN> cond_exp <CLOSEPAREN>

simple_cond ::= like_cond
 | null_cond
 | between_cond
 | in_cond
 | comparison_cond

null_cond ::= row_constructor <IS> ( <NOT> )? <NULL>

comparison_cond ::= row_constructor comparison_operator row_constructor

between_cond ::= row_constructor ( <NOT> )? <BETWEEN> row_constructor
      <AND> row_constructor

in_cond ::= row_constructor ( <NOT> )? <IN> <OPENPAREN> ( expression_list )
      <CLOSEPAREN>

row_constructor ::= expression

comparison_operator ::= <LESSEQUAL>
 | <GREATEREQUAL>
 | <NOTEQUAL>
 | <NOTEQUAL2>
 | <EQUAL>
 | <LESS>
 | <GREATER>

like_cond ::= string_exp ( <NOT> )? <LIKE> string_exp

expression_list ::= expression ( <COMMA> expression )?

expression ::= <STRING_LITERAL>
 | <OPENPAREN> <STRING_LITERAL> <CLOSEPAREN>
 | numeric_exp

numeric_exp ::= numeric_term ( ( <PLUS> | <MINUS> ) numeric_exp )?

numeric_term ::= numeric_factor ( ( <ASTERISK> | <SLASH> ) numeric_term )?

numeric_factor ::= ( <PLUS> | <MINUS> )? numeric_primary

numeric_primary ::= <INTEGER_LITERAL>
 | <FLOATING_POINT_LITERAL>
 | aggregate_func
 | column_ref
 | <OPENPAREN> numeric_exp <CLOSEPAREN>

aggregate_func ::= <COUNT> <OPENPAREN> count_param <CLOSEPAREN>
 | ( <AVG> | <SUM> | <MIN> | <MAX> ) <OPENPAREN> ( <ALL> | <DISTINCT> )?
      numeric_exp <CLOSEPAREN>

count_param ::= <ASTERISK>
 | ( <ALL> | <DISTINCT> )? numeric_exp

string_exp ::= <STRING_LITERAL>
 | column_ref
 | <OPENPAREN> string_exp <CLOSEPAREN>

column_ref ::= <IDENTIFIER> ( <DOT> <IDENTIFIER> )?
Previous


Managing LDAP Directories

CFML applications use the cfldap tag to access and manage LDAP (Lightweight Directory Access Protocol) directories. This chapter provides information on how to use this tag to view, query, and update LDAP directories.

This chapter teaches you how to query and update an LDAP database. It does not assume that you are familiar with LDAP, and provides an introduction to LDAP directories and the LDAP protocol. However, it does assume that you have information on your LDAP database’s structure and attributes, and it does not explain how to create an LDAP directory or manage a directory server. To learn more about LDAP and LDAP servers, see your LDAP server documentation and published books on LDAP.

The examples in this chapter use the Airius sample LDAP database that is supplied with the Netscape and iPlanet Directory Servers.

Contents
  • About LDAP
  • The LDAP information structure
  • Using LDAP with ColdFusion
  • Querying an LDAP directory
  • Updating an LDAP directory
  • Advanced topics
Next


About LDAP

The LDAP protocol enables organizations to arrange and access directory information in a hierarchy. In this context, directory refers to a collection of information, such as a telephone directory, not a collection of files in a folder on a disk drive.

LDAP originated in the mid-1990s as a response to the need to access ISO X.500 directories from personal computers that had limited processing power. Since then, products such as iPlanet Server have been developed that are native LDAP directory servers. Several companies now provide LDAP access to their directory servers, including Novell NDS, Microsoft Active Directory Services (ADS), Lotus Domino, and Oracle.

An LDAP directory is typically a hierarchically structured database. Each layer in the hierarchy typically corresponds to a level of organizational structure.

The following example shows a simple directory structure:

This is a picture of the feature being described.

This example is fully symmetrical: all the entries at each layer are of the same type.

You can also structure an LDAP directory so that the layers under one entry contain different information from the layers under another entry.

The following figure show such an asymmetric directory:

This is a picture of the feature being described.

In this directory structure, the second level of the tree divides the directory into two organizational units: people and groups. The third level contains entries with information that is specific to the organizational unit. Each person’s entry includes a name, e-mail address, and telephone number. Each group’s entry includes the names of group members.

This complexity and flexibility is a key to LDAP's usefulness. With it, you can represent any organizational structure.

LDAP offers performance advantages over conventional databases for accessing hierarchical, directory-like information that is read frequently and changed infrequently.

Although LDAP is often used for e-mail, address, telephone, or other organizational directories, it is by no means limited to these types of applications. For example, you can store ColdFusion Server Advanced Security information in an LDAP database.


The LDAP information structure

The following sections describe the LDAP information structure: the elements of an LDAP directory and how they are structured. These sections describe the following basic LDAP concepts:

  • Entry
  • Attribute
  • Distinguished name
  • Schema, including the object type and attribute class


Entry

The basic information object of LDAP is the entry. An entry is composed of one or more attributes. Entries are subject to content rules defined by the directory schema (see Schema ).

Each node, not just the terminal nodes, of an LDAP directory is an entry. In the preceding figures, each item is an entry. For example, in the first diagram, both USA and Ferrari are entries. The USA entry’s attributes could include a Language attribute, and the Ferrari entry could include an entry for the chief executive officer.


Attribute

An LDAP directory entry consists of one or more attributes. Attributes have types and values. The type determines the information that the values can contain. The type also specifies how the value is processed. For example, the type determines whether an attribute can have multiple values. The mail attribute type, which contains an e-mail address, is multivalued so you can store multiple e-mail addresses for one person.

Some commonly-used attribute types have short keyword type names. Often these correspond to longer type names, and the two names can be used interchangeably. The following table lists common attribute type keywords used in LDAP directories:

Keyword | Long name | Comment
c | CountryName |
st | stateOrProvinceName |
l | LocalityName | typically, city, but can be any geographical unit
street | StreetAddress |
o | OrganizationName |
ou | OrganizationalUnitName |
cn | CommonName | typically, first and last name
sn | SurName |
dc | domaincomponent |
mail | mail | e-mail address

At the time this chapter was written, Netscape provided a list of standard Attribute names on its Web site, at:

http://developer.netscape.com/docs/manuals/directory/schema2/41/contents.htm

For more information, see Attribute type.


Distinguished name (DN)

An entry’s distinguished name uniquely identifies it in the directory. A DN is made up of relative distinguished names (RDN)s. An RDN identifies the entry among the children of its parent entry. For example, in the first figure in About LDAP, the RDN for the Ferrari entry is “o=Ferrari”.

An entry’s DN consists of an entry’s RDN followed by the DN of its parent. In other words, it consists of the RDNs for the entry and each of the entry’s parent entries, up to the root of the directory tree. The RDNs are separated by commas and optional spaces. For example, in the first figure, the DN for the Ferrari entry is “o=Ferrari, c=Italy”.

As with file system pathnames and URLs, entering the correct LDAP name format is essential to successful search operations.

Note: The RDN is an attribute of a directory entry. The full DN is not. However, you can output the full DN by specifying "dn" in a query’s attributes list. For more information, see the CFML Reference. ColdFusion always returns DNs with spaces after the commas.

A multivalued RDN is made up of more than one attribute-value pair. In multivalued RDNs, the attribute-value pairs are separated by plus signs (+). In the sample directories, individuals could have complex RDNs consisting of their common name and their e-mail address; for example, “cn=Robert Boyd + mail=rjboyd@macromedia.com”.


Schema

The concepts of schemas and object classes are central to a thorough understanding of LDAP. Although detailed descriptions of them are beyond the scope of this chapter, the following sections provide enough information to use the cfldap tag effectively.

A directory schema is a set of rules that determines what can be stored in a directory. It defines, at a minimum, the following two basic directory characteristics:

  • The object classes to which entries can belong
  • The directory attribute types


Object class

Object classes enable LDAP to group related information. Frequently, an object class corresponds to a real object or concept, such as a country, person, room, or domain (in fact, these are all standard object type names). Each entry in an LDAP directory must belong to one or more object classes.

The following characteristics define an object class:

  • The class name
  • A unique object ID that identifies the class
  • The attribute types that entries of the class must contain
  • The attribute types that entries of the class can optionally contain
  • (Optional) A superior class from which the class is derived

If an entry belongs to a class that derives from another class, the entry’s objectclass attribute lists the lowest-level class and all the superior classes from which the lowest-level class derives.

When you add, modify, or delete a directory entry, you must treat the entry’s object class as a possibly multivalued attribute. For example, when you add a new entry, you specify the object class in the cfldap tag attributes attribute. To retrieve an entry’s object class names, specify “objectclass” in the list of query attributes. To retrieve entries that provide a specific type of information, you can use the object class name in the cfldap tag filter attribute.


Attribute type

A schema’s attribute type specification defines the following properties:

  • The attribute type name
  • A unique object ID that identifies the attribute type
  • (Optional) An indication of whether the type is single-valued or multivalued (the default is multivalued)
  • The attribute syntax and matching rules (such as case-sensitivity)

The attribute type definition can also determine limits on the range or size of values that the type represents, or provide an application-specific usage indicator. For standard attributes, a registered numeric ID specifies the syntax and matching rule information. For more information on attribute syntaxes, see ETF RFC 2252 at
http://www.ietf.org/rfc/rfc2252.txt.

Operational attributes, such as creatorsName or modifyTimeStamp, are managed by the directory service and cannot be changed by user applications.


Using LDAP with ColdFusion

The cfldap tag extends the ColdFusion query capabilities to LDAP network directory services. The cfldap tag lets you use LDAP in many ways, such as the following:

  • Create Internet White Pages so users can locate people and resources and get information about them
  • Provide a front end to manage and update directory entries
  • Build applications that incorporate data from directory queries in their processes
  • Integrate applications with existing organizational or corporate directory services

The cfldap tag action attribute supports the following operations on LDAP directories:

Action | Description
query | Returns attribute values from a directory.
add | Adds an entry to a directory.
modify | Adds, deletes, or changes the value of an attribute in a directory entry.
delete | Deletes an entry from a directory.
modifyDN | Renames a directory entry (changes its distinguished name).

The following table lists the attributes that are required and optional for each action. For more information on each attribute see the CFML Reference.

Action | Required attributes | Optional attributes
query | server, name, start, attributes | port, username, password, timeout, secure, rebind, referral, scope, filter, sort, sortControl startRow, maxRows, separator, delimiter
add | server, dn, attributes | port, username, password, timeout, secure, rebind, referral, separator, delimiter
modify | server, dn, attributes | port, username, password, timeout, secure, rebind, referral, modifyType, separator, delimiter
modifyDN | server, dn, attributes | port, username, password, timeout, secure, rebind, referral
delete | server, dn | port, username, password, timeout, secure, rebind, referral


Querying an LDAP directory

The cfldap tag lets you search an LDAP directory. The tag returns a ColdFusion query object with the results, which you can use as you would any query result. When you query an LDAP directory, you specify the directory entry where the search starts and the attributes whose values to return. You can specify the search scope and attribute content filtering rules and use other attributes to further control the search.


Scope

The search scope sets the limits of a search. The default scope is the level below the distinguished name specified in the start attribute. This scope does not include the entry identified by the start attribute. For example, if the start attribute is “ou=support, o=macromedia” the level below support is searched. You can restrict a query to the level of the start entry, or extend it to the entire subtree below the start entry.


Search filter

The search filter syntax has the form attribute operator value. The default filter, objectclass=*, returns all entries in the scope.

The following table lists the filter operators.

Operator | Example | Matches
=* | (mail=*) | All entries that contain a mail attribute.
= | (o=macromedia) | Entries in which the organization name is macromedia.
~= | (sn~=Hansen) | Entries with a surname that approximates Hansen. The matching rules for approximate matches vary among directory vendors, but anything that "sounds like" the search string should be matched. In this example, the directory server might return entries with the surnames Hansen and Hanson.
>= | (st>=ma) | The name "ma" and names appearing after "ma" in an alphabetical state attribute list.
<= | (st<=ma) | The name "ma" and names appearing before "ma" in an alphabetical state attribute list.
* | (o=macro*) | Organization names that start with "macro".
 | (o=*media) | Organization names that end with "media".
 | (o=mac*ia) | Organization names that start with "mac" and end with "ia". You can use more than one * operator in a string; for example, m*ro*dia.
 | (o=*med*) | Organization names that contain the string "med", including the exact string match "med".
& | (&(o=macromedia) (co=usa)) | Entries in which the organization name is "macromedia" and the country is "usa".
| | (|(o=macromedia) (sn=macromedia) (cn=macromedia)) | Entries in which the organization name is "macromedia" or the surname is "macromedia", or the common name is "macromedia".
! | (!(STREET=*)) | Entries that do not contain a StreetAddress attribute.

The Boolean operators & and | can operate on more than two attributes and precede all of the attributes on which they operate. You surround a filter with parentheses and use parentheses to group conditions.

If the pattern that you are matching contains an asterisk, left parenthesis, right parenthesis, backslash, or NUL character, you must use the following three-character escape sequence in place of the character:

Character | Escape sequence
* | \2A
( | \28
) | \29
\ | \5C
NUL | \00

For example, to match the common name St*r Industries, use the filter
(cn=St\2Ar Industries).

LDAP v3 supports an extensible match filter that permits server-specific matching rules. For more information on using extensible match filters, see your LDAP server documentation.


Searching and sorting notes

  • To search for multiple values of a multivalued attribute type, use the & operator to combine expressions for each attribute value. For example, to search for an entry in which cn=Robert Jones and cn=Bobby Jones, specify the following filter:
    • filter="(&(cn=Robert Jones)(cn=Bobby Jones))"
  • You can use object classes as search filter attributes; for example, you can use the following search filter:
    • filter="(objectclass=inetorgperson)"
  • To specify how query results are sorted, use the sort field to identify the attribute(s) to sort. By default, ColdFusion returns sorted results in case-sensitive ascending order. To specify descending order, case-insensitive sorting, or both, use the sortControl attribute.
  • ColdFusion requests the LDAP server to do the sorting. This can have two effects:
    • The sort order might differ between ColdFusion MX and previous versions.
    • If you specify sorting and the LDAP server does not support sorting, ColdFusion generates an error. To sort results from servers that do not support sorting, use a query of queries on the results.
  • If you use filter operators to construct sophisticated search criteria, performance might degrade if the LDAP server is slow to process the synchronous search routines that cfldap supports. You can use the cfldap tag timeout and maxRows attributes to control the apparent performance of pages that perform queries, by limiting the number of entries and by exiting the query if the server does not respond in a specified time.


Getting all the attributes of an entry

Typically, you do not use a query that gets all the attributes in an entry. Such a query would return attributes that are used only by the directory server. However, you can get all the attributes by specifying attributes="*" in your query.

If you do this, ColdFusion returns the results in a structure in which each element contains a single attribute name-value pair. The tag does not return a query object. ColdFusion does this because LDAP directory entries, unlike the rows in a relational table, vary depending on their object class.

For example, the following code retrieves the contents of the Airius directory:

<cfldap name="GetList"

server=#myServer#
action="query"
attributes="*"
scope="subtree"
start="o=airius.com"
sort="sn,cn">

This tag returns entries for all the people in the organization and entries for all the groups. The group entries have a different object class, and therefore different attributes from the person entries. If ColdFusion returned both types of entries in one query object, some rows would have only the group-specific attribute values and the other rows would have only person-specific attribute values. Instead, ColdFusion returns a structure in which each attribute is an entry.


Example: querying an LDAP directory

The following example uses the cfldap tag to get information about the people in the Airius corporation’s Santa Clara office. Users can enter all or part of a person’s name and get a list of matching names with their departments, e-mail addresses, and telephone numbers.

This example uses the sample Airius corporate directory that is distributed with the Netscape Directory Server. If you do not have access to this directory, modify the code to work with your LDAP directory.

To query an LDAP directory:

  1. Create a new file that looks like the following:
    2. <!--- This example shows the use of CFLDAP --->
<html>
<head> <title>cfldap Query Example</title> </head>

<h3>cfldap Query Example</h3>

<body>
<p>This tool queries the Airius.com database to locate all people in
the company's Santa Clara office whose common names contain the
text entered in the form.</p>

<p>Enter a full name, first name, last name, or name fragment.</p>

<form action="cfldap.cfm" method="POST">
   <input type="text" name="name"><br><br>
   <input type="submit" value="Search">
</form>

<!--- make the LDAP query --->
<!-- Note that some search text is required.
A search filter of cn=** would cause an error -->
<cfif (isdefined("form.name") AND (form.name IS NOT ""))>
   <cfldap
      server="ldap.airius.com"
      action="query"
      name="results"
      start="ou=People, o=Airius.com"
      scope="onelevel"
      filter="(&(cn=*#form.Name#*)(l=Santa Clara))"
      attributes="cn,sn,ou,mail,telephonenumber"
      sort="ou,sn"
      maxrows=100
      timeout=20
   >

<!--- Display results --->
   <table border=0 cellspacing=2 cellpadding=2>
    <tr>
         <th colspan=4><cfoutput>#results.RecordCount# matches found</cfoutput>
         </th>
    </tr>
    <tr>
         <th>Name</th>
         <th>Department</th>
         <th>E-Mail</th>
         <th>Phone</th>
    </tr>
   <cfoutput query="results">
    <tr>
         <td>#cn#</td>
         <td>#listFirst(ou)#</td>
         <td><a href="mailto:#mail#">#mail#</a></td>
         <td>#telephonenumber#</td>
    </tr>
   </cfoutput>
   </table>
</cfif>

</body>
</html>
  2. Change the server attribute from ldap.airius.com to the name of your installation of the Airius database.
  3. Save the page as cfldap.cfm and run it in your browser.


Reviewing the code

The following table describes the code.

Code
Description
<form action="cfldap.cfm" method="POST">
<input type="text" name="name">
<br><br>
<input type="submit" value="Search">
</form>
Uses a form to get the name or name fragment to search for.
<cfif (isdefined("form.name")
    AND (form.name IS NOT ""))>
Ensures that the user has submitted the form. This is necessary because the form page is also the action page. Ensures that the user entered search text.
<cfldap
  server="ldap.airius.com"
  action="query"
  name="results"
  start="ou=People, o=Airius.com"
   scope="onelevel"

  filter="(&(cn=*#form.Name#*)
    (l=Santa Clara))"

  attributes="cn,sn,ou,mail,
    telephonenumber"

  sort="ou,sn"

  maxrows=100
  timeout=20
>
Connects anonymously to LDAP server ldap.airius.com, query the directory, and return the results to a query object named results.
Starts the query at the directory entry that has the distinguished name ou=People, o=Airius.com, and searches the directory level immediately below this entry.
Requests records for entries that contain the location (l) attribute value "Santa Clara" and the entered text in the common name attribute.
Gets the common name, surname, organizational unit, e-mail address, and telephone number for each entry.
Sorts the results first by organization name, then by surname. Sorts in the default sorting order.
Limit the request to 100 entries. If the server does not return the data in 20 seconds, generates an error indicating that LDAP timed out.
<table border=0 cellspacing=2
    cellpadding=2>
  <tr>
    <th colspan=4>
      <cfoutput>#results.RecordCount#
         matches found</cfoutput>
    </th>
  </tr>
  <tr>
    <th>Name</th>
    <th>Department</th>
    <th>E-Mail</th>
    <th>Phone</th>
  </tr>
  <cfoutput query="results">
  <tr>
    <td>#cn#</td>
    <td>#ListFirst(ou)#</td>
    <td><a href="mailto:#mail#">#mail#
    </a></td>
    <td>#telephonenumber#</td>
  </tr>
  </cfoutput>
 </table>
</cfif>
Starts a table to display the output
Displays the number of records returned.
Displays the common name, department, e-mail address, and telephone number of each entry.
Displays only the first entry in the list of organizational unit values. (For more information, see the description that follows this table for more information.)

This search shows the use of a logical AND statement in a filter. It returns one attribute, the surname, that is used only for sorting the results.

In this query, the ou attribute value consists of two values in a comma-delimited list. One is the department name. The other is People. This is because the Airius database uses the ou attribute type twice:

  • In the distinguished names, at the second level of the directory tree, where it differentiates between organizational units such as people, groups, and directory servers
  • As the department identifier in each person’s entry

Because the attribute values are returned in order from the person entry to the directory tree root, the ListFirst function extracts the person’s department name.


Updating an LDAP directory

The cfldap tag lets does the following to LDAP directory entries:

  • Add
  • Delete
  • Add attributes
  • Delete attributes
  • Replace attributes
  • Change the DN (rename the entry)

These actions let you manage LDAP directory contents remotely.

The following sections show how to build a CFML page that lets you manage an LDAP directory:

  • Adding a directory entry
  • Deleting a directory entry
  • Updating a directory entry

The form displays directory entries in a table and includes a button that lets you populate the form fields based on the unique user ID.

The example CFML page does not add or delete entry attributes or change the DN. The sections Adding and deleting attributes of a directory entry and Changing a directory entry’s DN describe these operations.

To keep the code short, this example has limitations that are not appropriate in a production application. In particular, it has the following limitations:

  • If you enter an invalid user ID and click either the Update or the Delete button, ColdFusion generates a “No such object” error, because there is no directory entry to update or delete. Your application should verify that the ID exists in the directory before it tries to change or delete its entry.
  • If you enter a valid user ID in an empty form and click Update, the application deletes all the attributes for the User. The application should ensure that all required attribute fields contain valid entries before updating the directory.


Adding a directory entry

When you add an entry to an LDAP directory, you specify the DN, all the required attributes, including the entry’s object class, and any optional attributes. The following example builds a form that adds an entry to an LDAP directory.

To add an entry:

  1. Create a new file that looks like the following:
    2. <!--- set the LDAP server ID, user name, and password as variables
   here so they can be changed in only one place --->
<cfset myServer="ldap.myco.com">
<cfset myUserName="cn=Directory Manager">
<cfset myPassword="password">

<!--- Initialize the values used in form fields to empty strings --->
<cfparam name="fullNameValue" default="">
<cfparam name="surnameValue" default="">
<cfparam name="emailValue" default="">
<cfparam name="phoneValue" default="">
<cfparam name="uidValue" default="">

<!---When the form is submitted, add the LDAP entry --->
<cfif isdefined("Form.action") AND Trim(Form.uid) IS NOT "">
   <cfif Form.action is "add">
      <cfif Trim(Form.fullName) is "" OR Trim(Form.surname) is ""
         OR Trim(Form.email) is "" OR Trim(Form.phone) is "">
            <h2>You must enter a value in every field.</h2>
            <cfset fullNameValue=Form.fullName>
            <cfset surnameValue=Form.surname>
            <cfset emailValue=Form.email>
            <cfset phoneValue=Form.phone>
            <cfset uidValue=Form.uid>
      <cfelse>
         <cfset attributelist="objectclass=top, person,
               organizationalperson, inetOrgPerson;
            cn=#Trim(Form.fullName)#; sn=#Trim(Form.surname)#;
            mail=#Trim(Form.email)#;
            telephonenumber=#Trim(Form.phone)#;
            ou=Human Resources;
            uid=#Trim(Form.uid)#">
         <cfldap action="add"
            attributes="#attributeList#"
            dn="uid=#Trim(Form.uid)#, ou=People, o=Airius.com"
            server=#myServer#
            username=#myUserName#
            password=#myPassword#>
         <cfoutput><h3>Entry for User ID #Form.uid# has been added</h3>
         </cfoutput>
      </cfif>
   </cfif>
</cfif>

<html>
<head>
   <title>Update LDAP Form</title>
</head>
<body>
<h2>Manage LDAP Entries</h2>

<cfform action="update_ldap.cfm" method="post">
   <table>
      <tr><td>Full Name:</td>
         <td><cfinput type="Text"
             name="fullName"
             value=#fullNameValue#
             size="20"
             maxlength="30"
             tabindex="1"></td>
      </tr>
      <tr><td>Surname:</td>
         <td><cfinput type="Text"
            name="surname"
            Value= "#surnameValue#"
            size="20"
            maxlength="20"
            tabindex="2"></td>
      </tr>
      <tr>
         <td>E-mail Address:</td>
         <td><cfinput type="Text"
            name="email"
            value="#emailValue#"
            size="20"
            maxlength="20"
            tabindex="3"></td>
      </tr>
      <tr>
         <td>Telephone Number:</td>
         <td><cfinput type="Text"
            name="phone"
            value="#phoneValue#"
            size="20"
            maxlength="20"
            tabindex="4"></td>
      </tr>
      <tr>
         <td>User ID:</td>
         <td><cfinput type="Text"
            name="uid"
            value="#uidValue#"
            size="20"
            maxlength="20"
            tabindex="5"></td>
      </tr>
      <tr>
         <td colspan="2">
            <input type="Submit"
             name="action"
             value="Add"
             tabindex="8"></td>
      </tr>
   </table>
   <br>
   *All fields are required for Add<br>
</cfform>

<!---Output the user list --->
<h2>User List for the Human Resources Department</h2>
<cfldap name="GetList"
   server=#myServer#
   action="query"
   attributes="cn,sn,mail,telephonenumber,uid"
   start="o=Airius.com"
   scope="subtree"
   filter="ou=Human Resources"
   sort="sn,cn"
   sortControl="asc, nocase">

<table border="1">
   <tr>
      <th>Full Name</th>
      <th>Surname</th>
      <th>Mail</th>
      <th>Phone</th>
      <th>UID</th>
   </tr>
   <cfoutput query="GetList">
   <tr>
      <td>#GetList.cn#</td>
      <td>#GetList.sn#</td>
      <td>#GetList.mail#</td>
      <td>#GetList.telephonenumber#</td>
      <td>#GetList.uid#</td>
   </tr>
   </cfoutput>
</table>
</body>
</html>
  2. At the top of the file, change the myServer, myUserName, and myPassword variable assignments to values that are valid for your LDAP server.
  3. Save the page as update_ldap.cfm and run it in your browser.


Reviewing the code

The following table describes the code:

Code
Description
<cfset myServer="ldap.myco.com">
<cfset myUserName="cn=Directory
   Manager">
<cfset myPassword="password">
Initializes the LDAP connection information variables. Uses variables for all connection information so that any changes have to be made in only one place.
<cfparam name="fullNameValue"
   default="">
<cfparam name="surnameValue"
   default="">
<cfparam name="emailValue"
   default="">
<cfparam name="phoneValue"
   default="">
<cfparam name="uidValue" default="">
Sets the default values of empty strings for the form field value variables. The data entry form uses cfinput fields with value attributes so that the form can be prefilled and so that, if the user submits an incomplete form, ColdFusion can retain any entered values in the form when it redisplays the page.
<cfif isdefined("Form.action") AND
Trim(Form.uid) IS NOT "">
Ensures that the user entered a User ID in the form.
<cfif Form.action is "add">
If the user clicks Add, processes the code that follows.
<cfif Trim(Form.fullName) is ""
   OR Trim(Form.surname) is ""
   OR Trim(Form.email) is ""
   OR Trim(Form.phone) is "">
      <h2>You must enter a value in every
         field.</h2>
      <cfset fullNameValue=
         Form.fullName>
      <cfset surnameValue=
         Form.surname>
      <cfset emailValue=Form.email>
      <cfset phoneValue=Form.phone>
      <cfset uidValue=Form.uid>
If any field in the submitted form is blank, display a message and set the other form fields to display data that the user submitted.
<cfelse>
   <cfset attributelist=
      "objectclass=top,person,
         organizationalperson,
         inetOrgPerson;
      cn=#Trim(Form.fullName)#;
      sn=#Trim(Form.surname)#;
      mail=#Trim(Form.email)#;
         telephonenumber=
      #Trim(Form.phone)#;
      ou=Human Resources;
      uid=#Trim(Form.uid)#">
If the user entered data in all fields, sets the attributelist variable to specify the entry’s attributes, including the object class and the organizational unit (in this case, Human Resources).
The Trim function removes leading or trailing spaces from the user data.
   <cfldap action="add"
      attributes="#attributeList#"
      dn="uid=#Trim(Form.uid)#,
      ou=People, o=Airius.com"
      server=#myServer#
      username=#myUserName#
      password=#myPassword#>
   <cfoutput><h3>Entry for User ID
      #Form.uid# has been added</h3>
   </cfoutput>
</cfif>
</cfif>
</cfif>
Adds the new entry to the directory.
<cfform action="update_ldap.cfm"
       method="post">
   <table>
      <tr><td>Full Name:</td>
         <td><cfinput type="Text"
             name="fullName"
             value=#fullNameValue#
             size="20"
             maxlength="30"
             tabindex="1"></td>
      </tr>
.
.
.
      <tr><td colspan="2">
         <input type="Submit"
             name="action"
             value="Add"
             tabindex="6"></td>
      </tr>
   </table>
   <br>
   *All fields are required for Add<br>
</cfform>
Outputs the data entry form, formatted as a table. Each cfinput field always has a value, set by the value attribute when the page is called. The value attribute lets ColdFusion update the form contents when the form is redisplayed after the user clicks Add. The code that handles cases in which the user fails to enter all the required data uses this feature.
<cfldap name="GetList"
   server=#myServer#
   action="query"
   attributes="cn,sn,mail,
      telephonenumber,uid"
   start="o=Airius.com"
   scope="subtree"
   filter="ou=Human Resources"
   sort="sn,cn"
   sortControl="asc, nocase">
Queries the directory and gets the common name, surname, e-mail address, telephone number, and user ID from the matching entries.
Searches the subtree from the entry with the DN of o=Airius.com, and selects all entries in which the organizational unit is Human Resources.
Sorts the results by surname and then common name (to sort by last name, then first). Sorts in default ascending order that is not case-sensitive.
<table border="1">
   <tr>
   <th>Full Name</th>
   <th>Surname</th>
   <th>Mail</th>
   <th>Phone</th>
   <th>UID</th>
   </tr>
   <cfoutput query="GetList">
   <tr>
   <td>#GetList.cn#</td>
   <td>#GetList.sn#</td>
   <td>#GetList.mail#</td>
   <td>#GetList.telephonenumber#</td>
   <td>#GetList.uid#</td>
   </tr>
   </cfoutput>
</table>
</body>
</html>
Display the query results in a table.


Deleting a directory entry

To delete a directory entry, you must specify the entry DN.

The following example builds on the code that adds an entry. It adds Retrieve and Delete buttons. The Retrieve button lets you view a user’s information in the form before you delete it.

To delete an entry:

  1. Open update_ldap.cfm, which you created in Adding a directory entry.
  2. Between the first and second </cfif> tags, add the following code:
    3.    <cfelseif Form.action is "Retrieve">
      <cfldap name="GetEntry"
         server=#myServer#
         action="query"
         attributes="cn,sn,mail,telephonenumber,uid"
         scope="subtree"
         filter="uid=#Trim(Form.UID)#"
         start="o=Airius.com">
      <cfset fullNameValue = GetEntry.cn[1]>
      <cfset surnameValue = GetEntry.sn[1]>
      <cfset emailValue = GetEntry.mail[1]>
      <cfset phoneValue = GetEntry.telephonenumber[1]>
      <cfset uidValue = GetEntry.uid[1]>
   <cfelseif Form.action is "Delete">
      <cfldap action="delete"
         dn="uid=#Trim(Form.UID)#, ou=People, o=Airius.com"
         server=#myServer#
         username=#myUserName#
         password=#myPassword#>
      <cfoutput><h3>Entry for User ID #Form.UID# has been deleted
</h3></cfoutput>
  3. At the end of the code for the Add button (the input tag with Value=Add at the bottom of the form), delete the </td> end tag.
  4. After the end of the Add button input tag, add the following code:
    5.       &nbsp
      <input type="Submit"
          name="action"
          value="Retrieve"
          tabindex="7">
      &nbsp
      <input type="Submit"
          name="action"
          value="Delete"
          tabindex="8"></td>
  5. Save the file and run it in your browser.


Reviewing the code

The following table describes the code:

Code
Description
<cfelseif Form.action is "Retrieve">
   <cfldap name="GetEntry"
      server=#myServer#
      action="query"
      attributes="cn,sn,mail,
         telephonenumber,uid"
      scope="subtree"
      filter="uid=#Trim(Form.UID)#"
      start="o=Airius.com">
   <cfset fullNameValue=
      GetEntry.cn[1]>
   <cfset surnameValue=GetEntry.sn[1]>
   <cfset emailValue=GetEntry.mail[1]>
   <cfset phoneValue=
      GetEntry.telephonenumber[1]>
   <cfset uidValue=GetEntry.uid[1]>
If the user clicks Retrieve, queries the directory and gets the information for the specified User ID.
Sets the form field’s Value attribute to the corresponding query column.
This example uses the array index [1] to identify the first row of the GetEntry query object. Because the query always returns only one row, the index can be omitted.
<cfelseif Form.action is "Delete">
   <cfldap action="delete"
      dn="uid=#Trim(Form.UID)#,
         ou=People, o=Airius.com"
      server=#myServer#
      username=#myUserName#
      password="password">
   <cfoutput><h3>Entry for User
      ID #Form.UID# has been
      deleted</h3></cfoutput>
The user clicks delete, deletes the entry with the specified User ID and informs the user that the entry was deleted.
&nbsp
<input type="Submit"
   name="action"
   value="Retrieve"
   tabindex="7">
&nbsp
<input type="Submit"
   name="action"
   value="Delete"
   tabindex="8"></td>
Displays submit buttons for the Retrieve and Delete actions.


Updating a directory entry

The cfldap tag lets you change the values of entry attributes. To do so, you specify the entry DN in the dn attribute, and list the attributes to change and their new values in the attributes attribute.

The following example builds on the code that adds and deletes an entry. It can update one or more of an entry’s attributes. Because the UID is part of the DN, you cannot change it.

To update an entry:

  1. Open update_ldap.cfm, which you created in Adding a directory entry.
  2. Between the cfelseif Form.action is "Retrieve" block and the </cfif> tag, add the following code:
    3.    <cfelseif Form.action is "Update">
      <cfset attributelist="cn=#Trim(form.FullName)#; sn=#Trim(Form.surname)#;
mail=#Trim(Form.email)#;
         telephonenumber=#Trim(Form.phone)#">
      <cfldap action="modify"
         modifytype="replace"
         attributes="#attributeList#"
         dn="uid=#Trim(Form.UID)#, ou=People, o=Airius.com"
         server=#myServer#
         username=#myUserName#
         password=#myPassword#>
      <cfoutput><h3>Entry for User ID #Form.UID# has been updated</h3>
      </cfoutput>
  3. At the end of the code for the Delete button (the input tag with Value=Delete) at the bottom of the form), delete the </td> mark.
  4. After the end of the Delete button input tag, add the following code:
    5.       &nbsp
      <input type="Submit"
          name="action"
          value="Update"
          tabindex="9"></td>
  5. Save the file and run it in your browser.


Reviewing the code

The following table describes the code:

Code
Description
<cfelseif Form.action is "Update">
   <cfset attributelist="cn=#Trim
      (form.FullName)#;
      sn=#Trim(Form.surname)#;
      mail=#Trim(Form.email)#;
      telephonenumber=#Trim(Form.phone)#">
   <cfldap action="modify"
         modifytype="replace"
         attributes="#attributeList#"
            dn="uid=#Trim(Form.UID)#,
            ou=People, o=Airius.com"
         server=#myServer#
         username=#myUserName#
         password=#myPassword#>
      <cfoutput><h3>Entry for User ID
         #Form.UID# has been updated</h3>
      </cfoutput>
If the user clicks Update, sets the attribute list to the form field values and replaces the attributes for the entry with the specified UID.
Displays a message to indicate that the entry was updated.
This code replaces all of the attributes in a form, without checking whether they are blank. A more complete example would check for blank fields and either require entered data or not include the corresponding attribute in the attributes string.
&nbsp
<input type="Submit"
   name="action"
   value="Update"
   tabindex="9"></td>
Defines the Submit button for the update action.


Adding and deleting attributes of a directory entry

The following table lists the cfldap tag attributes that you must specify to add and delete LDAP attributes in an entry:

Action
cfldap syntax
Add attribute to entry
dn = "entry dn"
action = "modify"
modifyType = "add"
attributes = "attribname=attribValue[;...]"
Delete attribute from entry
dn = "entry dn"
action = "modify"
modifyType = "delete"
attributes = "attribName[;...]"

You can add or delete multiple attributes in one statement. To do this, use semicolons to separate the attributes in the attribute string.

The following example specifies the description and seealso LADP attributes:

attributes="description=Senior Technical Writer;seealso=writers"

You can change the character that you use to separate values of multivalued attributes in an attribute string. You can also change the character that separates attributes when a string contains multiple attributes. For more information, see Specifying an attribute that includes a comma or semicolon.

You can add or delete attributes only if the directory schema defines them as optional for the entry’s object class.


Changing a directory entry’s DN

To change the DN of an entry, you must provide the following information in the cfldap tag:

dn="original DN"
action="modifyDN"
attributes="dn=new DN"

For example:

<cfldap action="modifyDN"
   dn="#old_UID#, ou=People, o=Airius.com"
   attributes="uid=#newUID#"
   server=#myServer#
   username=#myUserName#
   password=#myPassword#>

The new DN and the entry attributes must conform to the directory schema; therefore, you cannot move entries arbitrarily in a directory tree. You can only modify a leaf only. For example, you cannot modify the group name if the group has children.

Note: LDAP v2 does not allow you to change entry DNs.


Advanced topics

The following sections present advanced topics that enable you to use LDAP directories more effectively.


Specifying an attribute that includes a comma or semicolon

LDAP attribute values can contain commas. The cfldap tag normally uses commas to separate attribute values in a value list. Similarly, an attribute can contain a semicolon, which cfldap normally uses to delimit (separate) attributes in an attribute list. To override the default separator and delimiter characters, you use the cfldap tag separator and delimiter attributes.

For example, assume you want to add the following attributes to an LDAP entry:

cn=Proctor, Goodman, and Jones
description=Friends of the company; Rationalists

Use the cfldap tag in the following way:

<cfldap action="modify"
   modifyType="add"
   attributes="cn=Proctor, Goodman, and Jones: description=Friends
of the company; Rationalists"
   dn="uid=goodco, ou=People, o=Airius.com"
   separator="&"
   delimiter=":"
   server=#myServer#
   username=#myUserName#
   password=#myPassword#>


Using cfldap output

You can create a searchable Verity collection from LDAP data. building a Verity collection using an LDAP directory, see .

The ability to generate queries from other queries is very useful when cfldap queries return complex data. For more information on querying queries, see


Viewing a directory schema

LDAP v3 exposes a directory's schema information in a special entry in the root DN. You use the directory root subschemaSubentry attribute to access this information.

The following ColdFusion query shows how to get and display the directory schema. It displays information from the schema’s object class and attribute type definitions. For object classes, it displays the class name, superior class, required attribute types, and optional attribute types. For attribute types, it displays the type name, type description, and whether the type is single- or multivalued.

The example does not display all the information in the schema. For example, it does not display the matching rules. It also does not display the object class IDs, attribute type IDs, attribute type syntax IDs, or the object class descriptions. (The object class description values are all “Standard Object Class.”)

Note: To be able to view the schema for an LDAP server, the server must support LDAP v3.

This example does not work on iPlanet Directory Server 5.0. It does work on a 4.x server.

To view the schema for an LDAP directory:

  1. Create a new file that looks like the following:
    2. <html>
<head>
   <title>LDAP Schema</title>
</head>

<body>
<!--- Start at Root DSE to get the subsechemaSubentry attribute --->
<cfldap
   name="EntryList"
   server="ldap.mycorp.com"
   action="query"
   attributes="subschemaSubentry"
   scope="base"
   start="">

<!--- Use the DN from the subschemaSubEntry attribute to get the schema --->
<cfldap
   name="EntryList2"
   server="ldap.mycorp.com"
   action="query"
   attributes="objectclasses, attributetypes"
   scope="base"
   filter="objectclass=*"
   start=#entryList.subschemaSubentry#>

<!--- Only one record is returned, so query loop is not required --->
<h2>Object Classes</h2>
<table border="1">
   <tr>
      <th>Name</th>
      <th>Superior class</th>
      <th>Must have</th>
      <th>May have</th>
   </tr>
   <cfloop index = "thisElement" list = #Entrylist2.objectclasses#>
      <cfscript>
         thiselement = Trim(thisElement);
         nameloc = Find("NAME", thisElement);
         descloc = Find("DESC", thisElement);
         suploc = Find("SUP", thisElement);
         mustloc = Find("MUST", thisElement);
         mayloc = Find("MAY", thisElement);
         endloc = Len(thisElement);
      </cfscript>
      <tr>
         <td><cfoutput>#Mid(thisElement, nameloc+6, descloc-nameloc-8)#
            </cfoutput></td>
         <cfif #suploc# NEQ 0>
            <td><cfoutput>#Mid(thisElement, suploc+5, mustloc-suploc-7)#
            </cfoutput></td>
         <cfelse>
            <td>NONE</td>
         </cfif>
         <cfif #mayloc# NEQ 0>
            <td><cfoutput>#Replace(Mid(thisElement, mustloc+6,
               mayloc-mustloc-9), " $ ", ", ", "all")#</cfoutput></td>
            <td><cfoutput>#Replace(Mid(thisElement, mayloc+5, endloc-mayloc-8),
               " $ ", ", ", "all")#</cfoutput></td>
         <cfelse>
            <td><cfoutput>#Replace(Mid(thisElement, mustloc+6,
               endloc-mustloc-9), " $ ", ", ", "all")#</cfoutput></td>
            <td>NONE</td>
         </cfif>
      </tr>
   </cfloop>
</table>
<br><br>

   <h2>Attribute Types</h2>
<table border="1" >
   <tr>
      <th>Name</th>
      <th>Description</th>
      <th>multivalued?</th>
   </tr>
   <cfloop index = "thisElement"
      list = #ReplaceNoCase(EntryList2.attributeTypes, ", alias", "<br> Alias",
      "all")# delimiters = ",">
      <cfscript>
         thiselement = Trim(thisElement);
         nameloc = Find("NAME", thisElement);
         descloc = Find("DESC", thisElement);
         syntaxloc = Find("SYNTAX", thisElement);
         singleloc = Find("SINGLE", thisElement);
         endloc = Len(thisElement);
      </cfscript>
      <tr>
         <td><cfoutput>#Mid(thisElement, nameloc+6, descloc-nameloc-8)#
            </cfoutput></td>
         <td><cfoutput>#Mid(thisElement, descloc+6, syntaxloc-descloc-8)#
            </cfoutput></td>
         <cfif #singleloc# EQ 0>
             <td><cfoutput>Yes</cfoutput></td>
         <cfelse>
             <td><cfoutput>No</cfoutput></td>
         </cfif>
      </tr>
   </cfloop>
</table>
</body>
</html>
  2. Change the server from ldap.mycorp.com to your LDAP server. You might also need to specify a user ID and password in the cfldap tag.
  3. Save the template as ldapschema.cfm in myapps under your Web root directory and view it in your browser.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfldap
   name="EntryList"
   server="ldap.mycorp.com"
   action="query"
   attributes="subschemaSubentry"
   scope="base"
   start="">
Gets the value of the subschemaSubentry attribute from the root of the directory server. The value is the DN of the schema.
<cfldap
   name="EntryList2"
   server="ldap.mycorp.com"
   action="query"
   attributes="objectclasses,
      attributetypes"
   scope="base"
   filter="objectclass=*"
   start=#entryList.subschemaSubentry#>
Uses the schema DN to get the objectclasses and attributetypes attributes from the schema.
<h2>Object Classes</h2>
<table border="1">
   <tr>
      <th>Name</th>
      <th>Superior class</th>
      <th>Must have</th>
      <th>May have</th>
   </tr>
   <cfloop index = "thisElement" list =
         #Entrylist2.objectclasses#>
      <cfscript>
         thisElement = Trim(thisElement);
         nameloc = Find("NAME",
            thisElement);
         descloc = Find("DESC",
            thisElement);
         suploc = Find("SUP", thisElement);
         mustloc = Find("MUST",
            thisElement);
         mayloc = Find("MAY", thisElement);
         endloc = Len(thisElement);
      </cfscript>
Displays the object class name, superior class, required attributes, and optional attributes for each object class in a table.
The schema contains the definitions of all object classes in a comma delimited list, so the code uses a list type cfloop tag.
The thisElement variable contains the object class definition. Trim off any leading or trailing spaces, then use the class definition field keywords in Find functions to get the starting locations of the required fields, including the Object class ID. (The ID is not displayed.)
Gets the length of the thisElement string for use in later calculations.
      <tr>
         <td><cfoutput>#Mid(thisElement,
            nameloc+6, descloc-nameloc-8)
            #</cfoutput></td>
         <cfif #suploc# NEQ 0>
            <td><cfoutput>#Mid(thisElement,
            suploc+5, mustloc-suploc-7)#
            </cfoutput></td>
         <cfelse>
            <td>NONE</td>
         </cfif>
         <cfif #mayloc# NEQ 0>
          <td><cfoutput>#Replace
            (Mid(thisElement, mustloc+6,
            mayloc-mustloc-9), " $ ", ", ",
            "all")#</cfoutput></td>
          <td><cfoutput>#Replace
            (Mid(thisElement, mayloc+5,
            endloc-mayloc-8), " $ ", ", ",
            "all")#</cfoutput></td>
         <cfelse>
          <td><cfoutput>#Replace
            (Mid(thisElement, mustloc+6,
            endloc-mustloc-9), " $ ", ", ",
            "all")#</cfoutput></td>
          <td>NONE</td>
         </cfif>
      </tr>
   </cfloop>
</table>
Displays the field values. Uses the Mid function to extract individual field values from the thisElement string.
The top object class does not have a superior class entry. Handles this special case by testing the suploc location variable. If the value is not 0, handles normally, otherwise, output "NONE".
There might not be any optional attributes. Handles this case similarly to the superior class. The calculation of the location of required attributes uses the location of the optional attributes if the field exists; otherwise, uses the end of the object class definition string.
   <h2>Attribute Types</h2>
   <table border="1" >
      <tr>
         <th>Name</th>
         <th>Description</th>
         <th>Multivalued?</th>
      </tr>
      <cfloop index = "thisElement" list =
          #ReplaceNoCase(attributeTypes, ",
          alias", "<br> Alias", "all")#
          delimiters = ",">
         <cfscript>
          thiselement = Trim(thisElement);
          nameloc = Find("NAME",
            thisElement);
          descloc = Find("DESC",
            thisElement);
          syntaxloc = Find("SYNTAX",
            thisElement);
          singleloc = Find("SINGLE",
            thisElement);
          endloc = Len(thisElement);
         </cfscript>
      <tr>
         <td><cfoutput>#Mid(thisElement,
            nameloc+6, descloc-nameloc-8)#
            </cfoutput></td>
         <td><cfoutput>#Mid(thisElement,
            descloc+6, syntaxloc-descloc-8)
            #</cfoutput></td>
         <cfif #singleloc# EQ 0>
             <td><cfoutput>Yes</cfoutput>
            </td>
         <cfelse>
             <td><cfoutput>No</cfoutput>
            </td>
         </cfif>
      </tr>
   </cfloop>
</table>
</cfloop>
Does the same types of calculations for the attribute types as for the object classes.
The attribute type field can contain the text ", alias for....". This text includes a comma, which also delimits attribute entries. Use the ReplaceNoCase function to replace any comma that precedes the word "alias" with an HTML <br> tag.
The attribute definition includes a numeric syntax identifier, which the code does not display, but uses its location in calculating the locations of the other fields.


Referrals

An LDAP database can be distributed over multiple servers. If the requested information is not on the current server, the LDAP v3 standard provides a mechanism for the server to return a referral to the client that informs the client of an alternate server. (This feature is also included in some LDAP v2-compliant servers.)

ColdFusion can handle referrals automatically. If you specify a non-zero referral attribute in the cfldap tag, ColdFusion sends the request to the server specified in the referral.

The referral attribute value specifies the number of referrals allowed for the request. For example, if the referral attribute is 1, and server A sends a referral to server B, which then sends a referral to server C, ColdFusion returns an error. If the referral attribute is 2, and server C has the information, the LDAP request succeeds. The value to use depends on the topology of the distributed LDAP directory, the importance of response speed, and the value of response completeness.

When ColdFusion follows a referral, the rebind attribute specifies whether ColdFusion uses the cfldap tag login information in the request to the new server. The default, No, sends an anonymous login to the server.


Managing LDAP security

When you consider how to implement LDAP security, you must consider server security and application security.


Server security

The cfldap tag supports secure socket layer (SSL) v2, security. This security provides certificate-based validation of the LDAP server. It also encrypts data transferred between the ColdFusion Server and the LDAP server, including the user password, and ensures the integrity of data passed between the servers.

The LDAP server sends a certificate that is securely “signed” by a trusted authority and identifies (authenticates) the sender. The ColdFusion server uses the certificate to ensure that the server is valid. The ColdFusion server does not send the LDAP server a certificate, and you must use the cfldap tag username and password attributes to authenticate yourself to the LDAP server.

To use security, first ensure that the LDAP server supports SSL v3 security.

Specify the cfldap tag secure attribute as follows:

secure = "cfssl_basic"

For example:

<cfldap action="modify"
   modifyType="add"
   atributes="cn=Lizzie"
   dn="uid=lborden, ou=People, o=Airius.com"
   server=#myServer#
   username=#myUserName#
   password=#myPassword#
   secure="cfssl_basic"
   port=636>

The port attribute specifies the server port used for secure LDAP communications, which is 636 by default. If you do not specify a port, ColdFusion attempts to connect to the default, nonsecure, LDAP port 389.


Application security

To ensure application security, you must prevent outsiders from gaining access to the passwords that you use in cfldap tags. The best way to do this is to use variables for your username and password attributes. You can set these variables on one encrypted application page. For more information on securing applications, see Securing Applications.

Previous


Building a Search Interface

You can provide a full-text search capability for documents and data sources on a ColdFusion site by enabling the Verity search engine.

This chapter describes how to build a Verity search interface with which users can perform powerful searches on your application. It also describes how to index your documents and data sources so that users can search them.

Contents
  • About Verity
  • Creating a search tool for ColdFusion applications
  • Using cfsearch
  • Working with record sets
Next


About Verity

To efficiently search through paragraphs of text or files of varying types, you need full-text search capabilities. ColdFusion includes the Verity search engine, which provides full-text indexing and searching.

The Verity engine performs searches against collections, not against the actual documents. A collection is a special database created by Verity that contains metadata that describes the documents that you have indexed. The indexing process examines documents of various types in a collection and creates a metadata description--the index--which is specialized for rapid search and retrieval operations.

ColdFusion's Verity implementation supports collections of three basic data types:

  • Text files such as HTML pages and CFML pages
  • Binary documents (see Supported file types)
  • Record sets returned from cfquery, cfldap, and cfpop queries

You can build collections from individual documents or from an entire directory tree. Collections can be stored anywhere, so you have much flexibility in accessing indexed data.

In your ColdFusion application, you can search multiple collections, each of which can focus on a specific group of documents or queries, according to subject, document type, location, or any other logical grouping. Because you can perform searches against multiple collections, you have substantial flexibility in designing your search interface.


Using Verity with ColdFusion

Here are some ways to use Verity with ColdFusion:

  • Index your website and provide a generalized search mechanism, such as a form interface, for executing searches.
  • Index specific directories containing documents for subject-based searching.
  • Index cfquery record sets, giving users the ability to search against the data. Because collections contain data optimized for retrieval, this method is much faster than performing multiple database queries to return the same data.
  • Index cfldap and cfpop query results.
  • Manage and search collections generated outside of ColdFusion using native Verity tools. This additional capability requires only that the full path to the collection be specified in the index and search commands.
  • Index e-mail generated by ColdFusion application pages and create a searching mechanism for the indexed messages.
  • Build collections of inventory data and make those collections available for searching from your ColdFusion application pages.
  • Support international users in a range of languages using the cfindex, cfcollection, and cfsearch tags.


Advantages of using Verity

Verity can index the output from queries so that you or a user can search against the record sets. Searching query results has a clear advantage over using SQL to search a database directly in speed of execution because metadata from the record sets are stored in a Verity index that is optimized for searching.

Performing a Verity search has the following advantages over other search methods:

  • You can reduce the programming overhead of query constructs by allowing users to construct their own queries and execute them directly. You need only be concerned with presenting the output to the client web browser.
  • Verity can index database text fields, such as notes and product descriptions, that cannot be effectively indexed by native database tools.
  • When indexing collections containing documents in formats such as Adobe Acrobat (PDF) and Microsoft Word, Verity scans for the document title (if one was entered), in addition to the document text, and displays the title in the search results list.
  • When Verity indexes web pages, it can return the URL for each document. This is a valuable document management feature.


Supported file types

The ColdFusion Verity implementation supports a wide array of file and document types. As a result, you can index web pages, ColdFusion applications, and many binary document types and produce search results that include summaries of these documents.

To support multiple WYSIWYG document types, Verity bundles the KeyView Filter Kit. The KeyView Filter Kit includes document filters that support the indexing and viewing of more than 45 native document formats. Numerous popular document suites and formats are supported, including Microsoft Office 95, 97, and 2000, Corel WordPerfect, Microsoft Word, Microsoft Excel, Lotus AMI Pro, and Lotus 1-2-3.

The Verity KeyView filters support the following formats:


Word Processing/Text Formats

  • Applix Words (v4.2, 4.3, 4.4, 4.41)
  • ASCII Text (All versions)
  • ANSI Text (All versions)
  • Folio Flat File (v3.1)
  • HTML (Verity Zone Filter)
  • Lotus AmiPro (v2.3)
  • Lotus Ami Professional Write Plus (All versions)
  • Lotus Word Pro (v96, 97, R9)
  • Maker Interchange Format (MIF) v5.5
  • Microsoft RTF (All versions)
  • Microsoft Word (v2, 6, 95, 97, 2000)
  • Microsoft Word Mac (v4, 5, 6, 98)
  • Microsoft Word PC (v4.,5, 6)
  • Microsoft Works (v1.0, 2.0, 3.0, 4.0)
  • Microsoft Write (v1.0, 2.0, 3.0)
  • PDF (Verity PDF Filter)
  • Text files (Verity Text Filter)
  • Unicode Text (All versions)
  • WordPerfect (v5.x, 6, 7, 8)
  • WordPerfect Mac (v2, 3)
  • XyWrite (v4.12)


Spreadsheet Formats

  • Applix Spreadsheets (v4.3, 4.4)
  • Corel QuattroPro (v7, 8)
  • Lotus 1-2-3 (v2, 3, 4, 5, 96, 97, R9)
  • Microsoft Excel (v3, 4, 5, 96, 97, 2000)
  • Microsoft Excel Mac (98)
  • Microsoft Works spreadsheet (v1.0, 2.0, 3.0, 4.0)


Presentation Formats

  • Applix Presents (v4.3, 4.4)
  • Corel Presentations (v7.0, 8.0)
  • Lotus Freelance (v96, 97, R9)
  • Microsoft PowerPoint (v4.0, 95, 97, 2000)
  • Microsoft PowerPoint Mac (98)


Picture Formats

  • AMI Draw Graphics (SDW)
  • Applix Graphics v4.3, 4.4
  • Fax Systems (TIFF CCITT) Groups 3 & 4
  • Computer Graphics Metafile (CGM)
  • Corel Draw CDR (TIFF Header)
  • DCX Fax
  • Encapsulated PostScript (EPS)
  • Enhanced Metafile (EMF)
  • JPEG File Interchange Format
  • Lotus Pic (PIC)
  • Mac PICT (raster content)
  • MacPaint (MAC)
  • Microsoft Excel Charts
  • Microsoft Windows Animated Cursor
  • Microsoft Windows Bitmap (BMP)
  • Microsoft Windows Cursor/Icon
  • Microsoft Windows Metafile (WMF)
  • PC PaintBrush (PCX)
  • Portable Network Graphics (PNG)
  • Sun Raster SGI RGB
  • Truevision Targa
  • TIFF
  • WordPerfect Graphics (WPG) v1, 2


Multimedia Formats

  • Audio Interchange File Format (AIFF)
  • Microsoft Sound (WAV)
  • MIDI (MID)
  • MPEG 1 Video (MPG)
  • MPEG 2 Audio
  • NeXT/Sun Audio (AU)
  • QuickTime Movie v2.0
  • Video for Windows v2.1


Support for international languages

ColdFusion supports Verity Locales in European and Asian languages. For European languages, ColdFusion uses LinguistX technology from Inxight; for Asian languages, ColdFusion uses ICU (IBM® Classes for Unicode) technology. For more information about installing Verity Locales, see Installing ColdFusion MX.

The default language for Verity collections is English. To index data in another supported language, select it from the drop-down list when you create a collection with the ColdFusion Administrator. In CFML, the cfcollection, cfindex, and cfsearch tags have an optional language attribute that you use to specify the language of the collection that you are searching. If you do not specify a language in these tags, ColdFusion checks the neo-verity.xml file for the collection’s language. If this is defined, ColdFusion uses that language.

Use the following table to find the correct value for the language attribute for your collection; for example, the following code creates a collection for simplified Chinese:

<cfcollection action = "create" collection = "lei_01"
  path = "c:\cfusionmx\verity\collections"
  language = "simplified_chinese">

The following table lists the languages names and attributes that ColdFusion supports:

Language | Language attribute | Localization technology
Arabic | arabic | ICU
Chinese (simplified) | simplified_chinese | ICU
Chinese (traditional) | traditional_chinese | ICU
Czech | czech | ICU
Danish | danish | LinguistX
Dutch | dutch | LinguistX
English | english | LinguistX
Finnish | finnish | LinguistX
French | french | LinguistX
German | german | LinguistX
Greek | greek | ICU
Hebrew | hebrew | ICU
Hungarian | hungarian | ICU
Italian | italian | LinguistX
Japanese | japanese | ICU
Korean | korean | ICU
Norwegian | norwegian | LinguistX
Norwegian (Bokmal) | bokmal | LinguistX
Norwegian (Nynorsk) | nynorsk | LinguistX
Polish | polish | ICU
Portuguese | portuguese | LinguistX
Russian | russian | ICU
Spanish | spanish | LinguistX
Swedish | swedish | LinguistX
Turkish | turkish | ICU

You can register collections in the Administrator or by creating a collection with the cfcollection tag. If you register a given collection with ColdFusion and you specify a language attribute, then you do not have to specify the language attribute when using cfindex and cfsearch for that collection. If you do not register a given collection with ColdFusion, the language defaults to English, unless you specify it in the language attribute for the cfindex and cfsearch tags for that collection.


Creating a search tool for ColdFusion applications

There are three main tasks in creating a search tool for your ColdFusion application:

  1. Create a collection.
  2. Index the collection.
  3. Design a search interface.

You can perform each task programmatically--that is, by writing CFML code. Alternatively, you can use the ColdFusion Administrator to create and index the collection. Also, ColdFusion Studio has a Verity Wizard that generates ColdFusion pages that index the collection and design a search interface. The following table summarizes the steps and available methods for creating the search tool:

Step | CFML | ColdFusion Administrator | Verity Wizard
Creating a collection | Yes | Yes | No
Indexing a collection | Yes | Yes | Yes
Designing a search interface | Yes | No | Yes

This chapter presents the non-code methods for developing a search tool, followed by code examples that perform the same task. If you have ColdFusion Studio and access to the ColdFusion Administrator, the fastest development method is:

  1. Create the collection with the ColdFusion Administrator.
  2. Use the Verity Wizard to index the collection and design a search interface.


Creating a collection with the ColdFusion Administrator

Use the following procedure to quickly create a collection with the ColdFusion Administrator:

To create a collection with the ColdFusion Administrator:

  1. In the ColdFusion Administrator, select Data & Services > Verity Collections.

    2. The Verity Collections page appears:

    This is a picture of the feature being described.

  2. Enter a name for the collection; for example, DemoDocs.
  3. Enter a path for the directory location of the new collection; for example, C:\cfusionmx\verity\collections\.

    4. By default, ColdFusion stores collections in \cf_root\verity\collections\ in Windows and in /cf_root/verity/collections in UNIX.

    Note: This is the location for the collection, not for the files that you will search.

  4. (Optional) Select a language other than English for the collection from the Language drop-down list.
  5. Click Create Collection.

    6. The name and full path of the new collection appears in the list of Connected Verity Collections:

    This is a picture of the feature being described.

    Note: You can map a collection currently available on your network or local disk by creating a local reference (an alias) for that collection. In this procedure, enter the collection alias as the collection name, and enter a UNC (Universal Naming Convention) path to the folder for the collection.

You have successfully created a collection, DemoDocs, that currently has no data. A collection becomes populated with data when you index it. For more information, see About indexing a collection.


About indexing a collection

A new collection is an empty shell that must be indexed before you search it. The indexing procedure also populates the collection with data contained in the collection’s files. Similar to creating a collection, you can index a collection either in the ColdFusion Administrator or programmatically.

Note: You can index and search against collections created outside of ColdFusion by using the external attribute of cfindex and cfsearch.

Use the following guidelines to determine which method to use:

Use the Administrator | Use the cfindex tag
To index document files | To index ColdFusion query results
When the collection does not require frequent updates | When the collection requires frequent updates
To create the collection without writing any CFML code | To dynamically update a collection from a ColdFusion application page
To create a collection once | When the collection requires updating by others

The cfcollection tag has the following action attribute values that can fix or improve your index:

  • repair Repairs the internal index files of a collection. This may take a few minutes for large collections.
  • optimize Optimizes a collection. Use this if you notice that your searches on a collection take longer than previously.


Updating an index

Documents are modified frequently in many user environments. After you index your documents, any changes that you make are not reflected in subsequent Verity searches until you reindex the collection. Depending on your environment, you can create a scheduled task to automatically keep your indexes current. For more information on scheduled tasks, see Administering ColdFusion MX.


Indexing and building a search interface with the Verity Wizard

If you have ColdFusion Studio, you can use the Verity Wizard to generate a basic search and index interface. Use the following procedure to quickly create a search application for a collection. This procedure assumes the following:

  • There is an empty Verity collection to hold the indexed data. For details on how to use the ColdFusion Administrator to create a collection, see Creating a collection with the ColdFusion Administrator.
  • A directory contains files of several types, such as text, word processing, spreadsheet, and HTML. If this directory is within your web_root, then you can view the files from the web browser.
  • Some of these files contain a search target word(s).
  • There is an available directory to hold the four ColdFusion pages that the wizard generates.

To build a search interface using the Verity Wizard:

  1. In ColdFusion Studio, select File > New.
  2. In the New Document window, click the CFML tab.
  3. Double-click the Verity Wizard.

    4. The Verity Application window appears:

    This is a picture of the feature being described.

  4. Enter the following information:

    Field
    Description
    Example
    Title
    Appears at the top of each generated ColdFusion page.
    Search CF Documentation
    Directory
    Contains the generated ColdFusion pages. The directory should be under your web_root so that you can view ColdFusion pages in the web browser.
    web_root\vw_generated

  5. Click Next.

    6. The Select Collection window appears:

    This is a picture of the feature being described.

  6. Enter the following information:

    Field
    Description
    Example
    Collection Name
    The name of the collection you created in the ColdFusion Administrator (or by using the cfcollection tag).
    DemoDocs
    Language
    The language used to create the collection (English is the default).
    english

  7. Click Next.

    8. The Indexing Settings window appears:

    This is a picture of the feature being described.

  8. Enter the following information:

    Field
    Description
    Example
    Directory Path
    The directory that contains the documents to be indexed.
    C:\CFusionMX\wwwroot\cfdocs
    Recursively Index Subdirectories
    (Optional) Extends the indexing operation to all directories below the selected path.
    enabled (default)
    File Extensions
    The type(s) of files to index. Use a comma to separate multiple file types.
    .htm, .html, .xml
    Return URL
    (Optional) If your documents are beneath the web_root, enter a URL that corresponds to the Directory Path.
    http://127.0.0.1:8500/cfdocs/

  9. Click Finish.

    10. The wizard generates four ColdFusion pages to the directory you specified in step 4 and displays an output summary:

    This is a picture of the feature being described.

    Note: The file names are in the format pagetitle_Vpagename.cfm, where pagetitle is the value you specified in step 4 and pagename is SearchForm, SearchResult, OpenFile, or PathIndexing.

  10. Click Close.

    11. The wizard closes and the files open in ColdFusion Studio (you can adjust its size to display all file tabs).

  11. Browse the SearchForm page in ColdFusion Studio.

    12. Alternatively, you can use the web browser; if you do so, enter an HTTP URL that corresponds to your SearchForm, such as:
    http://127.0.0.1:8500/vw_generated/SearchCFDocumentation_VSearchForm.cfm.

    This is a picture of the feature being described.

  12. Click the Index link at the bottom of the page.

    13. A confirmation message appears when indexing successfully completes.

  13. Click the web browser’s back button to return to the search form.
  14. Enter your search term(s); for example, Verity AND data source.

    15. Tip: For more information on Verity’s search syntax, see Using Verity Search Expressions.

  15. Click Search.

    16. In ColdFusion Studio 4.x, the following compilation error may display:

    Invalid parser construct found on line 46 at position 49. ColdFusion was looking at the following text:'

    To correct this error:

    1. In ColdFusion Studio, open the SearchResult page in Edit mode; for example, WizardDocDemo_VSearchResult.cfm.
    2. In line 46, delete the pound signs that precede the hexadecimal color codes. The correct code is:

      3. <TR bgcolor="#IIf(CurrentRow Mod 2, DE('FFFFFF'), DE('FFFFCF'))#">

    3. Save the file.
    4. Browse the SearchForm page and enter the search target.

      5. Your search results appear:

      This is a picture of the feature being described.

      If you entered a Return URL value and your documents are beneath your web_root (as in this procedure), you can click the link to open them.

You now have Verity search capability for your ColdFusion application. You can edit the generated ColdFusion pages or copy the generated code into the current pages to better integrate with your application.

You can create a search interface without using the Verity Wizard. The remainder of this chapter describes how to write CFML code that is functionally identical to the pages generated by the wizard. You can write the code using your text editor and preview it in the web browser.


Creating a ColdFusion search tool programmatically

You can create a Verity search tool for your ColdFusion application in CFML. Although writing CFML code can take more development time than using these tools, there are situations in which writing code is the preferred development method.


Creating a collection with the cfcollection tag

The following are cases in which you might prefer using the cfcollection tag rather than the ColdFusion Administrator to create a collection:

  • You want your ColdFusion application to be able to create, delete, and maintain a collection.
  • You do not want to expose the ColdFusion Administrator to users.
  • You want to create indexes on servers that you cannot access directly; for example, if you use a hosting company.

When using the cfcollection tag, you can specify the same attributes as in the ColdFusion Administrator:

  • action (Optional) The action to perform on the collection (create, delete, repair, or optimize). The default value for the action attribute is list. For more information, see CFML Reference.
  • collection The name of the new collection, or the name of a collection upon which you will perform an action.
  • path The location for the Verity collection.
  • language (Optional) The language used to create the collection (English, by default).

You can create a collection by directly assigning a value to the name attribute of the cfcollection tag, as shown in the following code:

<cfcollection action = "create"
   collection = "a_new_collection"
   path = "c:\cfusionmx\verity\collections\">

If you want your users to be able to dynamically supply the name and location for a new collection, use the following procedures to create form and action pages.

To create a simple collection form page:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Collection Creation Input Form</title>
</head>

<body>
<h2>Specify a collection</h2>
<form action="collection_create_action.cfm" method="POST">

   <p>Collection name:
   <input type="text" name="CollectionName" size="25"></p>

   <p>What do you want to do with the collection?</p>
   <input type="radio"
      name="CollectionAction"
      value="Create" checked>Create<br>
   <input type="radio"
      name="CollectionAction"
      value="Repair">Repair<br>
   <input type="radio"
      name="CollectionAction"
      value="Optimize">Optimize<br>
   <input type="submit"
      name="submit"
      value="Submit">
</form>

</body>
</html>
  2. Save the file as collection_create_form.cfm in the myapps directory under the web_root.

Note: The form will not work until you write an action page for it, which is the next procedure.

To create a collection action page:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>cfcollection</title>
</head>

<body>
<h2>Collection creation</h2>

<cfoutput>

   <cfswitch expression=#Form.collectionaction#>
      <cfcase value="Create">
         <cfcollection action="Create"
         collection="#Form.CollectionName#"
         path="c:\cfusionmx\verity\collections\">
         <p>The collection #Form.CollectionName# is created.
      </cfcase>

      <cfcase value="Repair">
         <cfcollection action="Repair"
         collection="#Form.CollectionName#">
         <p>The collection #Form.CollectionName# is repaired.
      </cfcase>

      <cfcase value="Optimize">
         <cfcollection action="Optimize"
         collection="#Form.CollectionName#">
         <p>The collection #Form.CollectionName# is optimized.
      </cfcase>

      <cfcase value="Delete">
         <cfcollection action="Delete"
         collection="#Form.CollectionName#">
         <p>Collection deleted.
      </cfcase>
   </cfswitch>
</cfoutput>
</body>
</html>
  2. Save the file as collection_create_action.cfm in the myapps directory under the web_root.
  3. In the web browser, enter the following URL to display the form page:

    4. http://127.0.0.1/myapps/collection_create_form.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.

  4. Enter a collection name; for example, CodeColl.
  5. Verify that Create is selected and submit the form.
  6. (Optional) In the ColdFusion Administrator, reload the Verity Collections page.

    7. The name and full path of the new collection appears in the list of Connected Verity Collections.

You successfully created a collection, named CodeColl, that currently has no data. For information on indexing your collection using CFML, see Indexing a collection using the cfindex tag.


Indexing a collection using the cfindex tag

You can index a collection in CFML using the cfindex tag, which eliminates the need to use the ColdFusion Administrator. When using this tag, the following attributes correspond to values entered in the ColdFusion Administrator:

  • collection The name of the collection. If you are indexing an external collection (external = "Yes"), you must also specify the fully qualified path for the collection.
  • action (Optional) Can be update (the default action), delete, purge, or refresh.
  • extensions (Optional) The delimited list of file extensions that ColdFusion uses to index files if type="Path".
  • key (Optional) The path containing the files you are indexing if type="path".
  • URLpath (Optional) The URL path for files if type="file" and type="path". When the collection is searched with cfsearch, the pathname is automatically prefixed to filenames and returned as the url attribute.
  • recurse (Optional) Yes or No. Yes specifies, if type = "Path", that directories below the path specified in the key attribute are included in the indexing operation.
  • language (Optional) The language of the collection. English is the default.

You can use form and action pages similar to the following examples to select and index a collection.

To select which collection to index:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Select the Collection to Index</title>
</head>
<body>

<h2>Specify the index you want to build</h2>

<form method="Post" action="collection_index_action.cfm">
   <p>Enter the collection you want to index:
   <input type="text" name="IndexColl" size="25" maxLength="35"></p>
   <p>Enter the location of the files in the collection:
   <input type="text" name="IndexDir" size="50" maxLength="100"></p>

   <input type="submit" name="submit" value="Index">

</form>

</body>
</html>
  2. Save the file as collection_index_form.cfm in the myapps directory under the web_root.

Note: The form will not work until you write an action page for it, which is the next procedure.

To use cfindex to index a collection:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Creating Index</title>
</head>
<body>
<h2>Indexing Complete</h2>

<cfindex collection="#Form.IndexColl#"
   action="refresh"
   extensions=".htm, .html, .xls, .txt, .mif, .doc"
   key="#Form.IndexDir#"
   type="path"
   urlpath="#Form.IndexDir#"
   recurse="Yes"
   language="English">

<cfoutput>
   The collection #Form.IndexColl# has been indexed.
</cfoutput>
</body>
</html>
  2. Save the file as collection_index_action.cfm.
  3. In the web browser, enter the following URL to display the form page:

    4. http://127.0.0.1/myapps/collection_index_form.cfm

    The following figure shows how the output appears:

    This is a picture of the feature being described.

  4. Enter a collection name; for example, CodeColl.
  5. Enter a file location; for example, C:\CFusionMX\wwwroot\vw_files.
  6. Click Index.

    7. A confirmation message appears upon successful completion.

Note: For information about using the cfindex tag with a database to index a collection, see Using database-directed indexing.


Indexing a collection with the ColdFusion Administrator

As an alternative to programmatically indexing a collection and to using the Verity Wizard, use the following procedure to quickly index a collection with the ColdFusion Administrator.

To use ColdFusion Administrator to index a collection:

  1. In the list of Connected Verity Collections, select a collection name; for example, CodeColl.
  2. Click Index to open the index page.
  3. For File Extensions, enter the type(s) of files to index. Use a comma to separate multiple file types; for example, .htm, .html, .xls, .txt, .mif, .doc.
  4. Enter (or Browse to) the directory path that contains the files to be indexed; for example, C:\Inetpub\wwwroot\vw_files.
  5. (Optional) To extend the indexing operation to all directories below the selected path, select the Recursively index subdirectories check box.
  6. (Optional) Enter a Return URL to prepend to all indexed files.

    7. This step lets you create a link to any of the files in the index; for example,

    http://127.0.0.1/vw_files/.

  7. (Optional) Select a language other than English.

    8. For more information, see Support for international languages.

  8. Click Submit Changes.

    9. The indexing process. On completion, the Verity Collections page appears.

    Note: The time required to generate the index depends on the number and size of the selected files in the path.

This interface lets you easily build a very specific index based on the file extension and path information you enter. In most cases, you do not need to change your server file structures to accommodate the generation of indices.


Using cfsearch

You use the cfsearch tag to search an indexed collection. Searching a Verity collection is similar to a standard ColdFusion query: both use a dedicated ColdFusion tag that requires a name attribute for their searches. The following table compares the two tags:

cfquery | cfsearch
Searches a data source | Searches a collection
Requires name attribute | Requires name attribute
Uses SQL statements to specify search criteria | Uses a criteria attribute to specify search criteria
Returns variables keyed to database table field names | Returns a unique set of variables
Uses cfoutput to display query results | Uses cfoutput to display search results

Note: You receive an error if you attempt to search a collection that has not been indexed.

The following are important attributes for the cfsearch tag:

  • name The name of the search query.
  • collection The name of the collection(s) being searched. Use a fully qualified path for an external collection. Separate multiple collections with a comma; for example, collection = "sprocket_docs,CodeColl".
  • criteria The search target (can be dynamic).

Each cfsearch returns variables that provide information about the search:

  • RecordCount The total number of records returned by the search.
  • CurrentRow The current row of the record set being processed by cfoutput.
  • RecordsSearched The total number of records in the index that were searched. If no records were returned in the search, this property returns a null value.

Note: To use cfsearch to search a Verity K2 Server collection, the collection attribute must be the collection's unique alias name as defined in the k2server.ini and the external attribute must be “No” (the default). For more detail, see Administering ColdFusion MX.

You can use search form and results pages similar to the following examples to search a collection.

To create a search form:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Searching a collection</title>
</head>
<body>
<h2>Searching a collection</h2>

<form method="post" action="collection_search_action.cfm">
   <p>Enter search term(s) in the box below. You can use AND, OR, NOT, and
   parentheses. Surround an exact phrase with quotation marks.</p>
   <p><input type="text" name="criteria" size="50" maxLength="50">
   </p>
   <input type="submit" value="Search">
</form>
</body>
</html>
  2. Save the file as collection_search_form.cfm.

Enter a search target word(s) in this form, which passes this as the variable criteria to the action page, which displays the search results.

To create the results page:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Search Results</title>
</head>
<body>
<cfsearch
   name = "codecoll_results"
   collection = "CodeColl"
   criteria = "#Form.Criteria#">

<h2>Search Results</h2>
<cfoutput>
Your search returned #codecoll_results.RecordCount# file(s).
</cfoutput>

<cfoutput query="codecoll_results">
   <p>
   File: <a href="#URL#">#Key#</a><br>
   Document Title (if any): #Title#<br>
   Score: #Score#<br>
   Summary: #Summary#</p>
</cfoutput>
</body>
</html>
  2. Save the file as collection_search_action.cfm.
  3. View collection_search_form.cfm in the web browser.

    4. This is a picture of the feature being described.

  4. Enter a target word(s) and click Search.

    5. The following figure shows how the output appears:

    This is a picture of the feature being described.

Note: As part of the indexing process, Verity automatically produces a summary of every document file or every query record set that gets indexed. The default summary selects the best sentences, based on internal rules, up to a maximum of 500 characters. Every cfsearch operation returns summary information by default. For more information on this topic, see Using Verity Search Expressions.


Working with record sets

The cfquery, cfldap, and cfpop tags return the results of a database query in a record set. In some cases, you may want to search the record set. This section describes the reasons and procedures for indexing the results of database, LDAP, and pop queries. It also describes how a database can direct the indexing process, using different values for the type attribute of the cfindex tag.


Indexing database record sets

These are the steps to perform a Verity search on record sets:

  1. Write a query to generate a record set.
  2. Index the record set.
  3. Search the record set.

Performing searches against a Verity collection rather than using cfquery provides faster access, because the Verity collection indexes the database. Use this technique instead of cfquery in the following cases:

  • You want to index textual data. You can search Verity collections containing textual data much more efficiently with a Verity search than with a SQL query.
  • You want to give your users access to data without interacting directly with the data source itself.
  • You want to improve the speed of queries.
  • You want your users to run queries but not update database tables.

Indexing the record set from a ColdFusion query involves an extra step not required when you index documents. You must code the query and output parameters, and then use the cfindex tag to index the record set from a cfquery, cfldap, or cfpop query.

You write a cfquery that retrieves the data to index, then you pass this information to a cfindex tag, which populates the collection. The cfindex tag contains the following attributes that correspond to the data source:

Cfindex attribute | Description
key | primary key of the data source table
title | specifies a query column name
body | column(s) that you want to search for the index

The following procedure assumes that you have a Verity collection named CodeColl. For more information, see Creating a collection with the cfcollection tag. The following procedure uses the CompanyInfo data source that is installed with ColdFusion.

To index a ColdFusion query:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Adding Query Data to an Index</title>
</head>
<body>

<!--- retrieve data from the table --->
<cfquery name="getEmps" datasource="CompanyInfo">
   SELECT * FROM EMPLOYEE
</cfquery>

<!--- update the collection with the above query results --->
<cfindex
   query="getEmps"
   collection="CodeColl"
   action="Update"
   type="Custom"
   key="Emp_ID"
   title="Emp_ID"
   body="Emp_ID,FirstName,LastName,Salary">

<h2>Indexing Complete</h2>

<!--- output the record set --->
<p>Your collection now includes the following items:</p>
<cfoutput query="getEmps">
   <p>#Emp_ID# #FirstName# #LastName# #Salary#</p>
</cfoutput>
</body>
</html>
  2. Save the file as collection_db_index.cfm in the myapps directory under the web_root.
  3. Open the file in the web browser to index the collection.

    4. The resulting record set displays:

    This is a picture of the feature being described.

Using the cfindex tag for indexing tabular data is similar to indexing documents, with two exceptions:

  • You set the type attribute to custom when indexing tabular data.
  • You refer to column names from the cfquery in the body attribute.

To search and display database records:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Searching a collection</title>
</head>
<body>

<h2>Searching a collection</h2>

<form method="post" action="collection_db_results.cfm">
   <p>Collection name: <input type="text" name="collname" size="30"
maxLength="30"></p>

   <p>Enter search term(s) in the box below. You can use AND, OR, NOT,
   and parentheses. Surround an exact phrase with quotation marks.</p>
   <p><input type="text" name="criteria" size="50" maxLength="50">
   </p>
   <p><input type="submit" value="Search"></p>
</form>

</body>
</html>
  2. Save the file as collection_db_search_form.cfm in the myapps directory under the web_root.

    3. This file is similar to collection_search_form.cfm, except the form uses collection_db_results.cfm, which you create in the next step, as its action page.

  3. Create another ColdFusion page with the following content:
    4. <html>
<head>
<title>Search Results</title>
</head>

<body>

<cfsearch
   collection="#Form.collname#"
   name="getEmps"
   criteria="#Form.Criteria#">

<!--- output the record set --->
<cfoutput>
Your search returned #getEmps.RecordCount# file(s).
</cfoutput>

<cfoutput query="getEmps">
   <p><table>
   <tr><td>Title: </td><td>#Title#</td></tr>
   <tr><td>Score: </td><td>#Score#</td></tr>
   <tr><td>Key: </td><td>#Key#</td></tr>
   <tr><td>Summary: </td><td>#Summary#</td></tr>
   <tr><td>Custom 1:</td><td>#Custom1#</td></tr>
   <tr><td>Column list: </td><td>#ColumnList#</td></tr>
</table></p>

</cfoutput>

</body>
</html>
  4. Save the file as collection_db_results.cfm in the myapps directory under the web_root.
  5. View collection_db_search_form.cfm in the web browser and enter the name of the collection and search terms; for example, search the CodeColl collection for lightner or crooks.

    6. The following figure shows how the output appears:

    This is a picture of the feature being described.


Indexing cfldap query results

The widespread use of the Lightweight Directory Access Protocol (LDAP) to build searchable directory structures, internally and across the web, gives you opportunities to add value to the sites that you create. You can index contact information or other data from an LDAP-accessible server and allow users to search it.

When creating an index from an LDAP query, remember the following considerations:

  • Because LDAP structures vary greatly, you must know the server’s directory schema and the exact name of every LDAP attribute that you intend to use in a query.
  • The records on an LDAP server can be subject to frequent change, so re-index the collection before processing a search request.

In the following example, the search criterion is records with a telephone number in the 617 area code. Generally, LDAP servers use the Distinguished Name (dn) attribute as the unique identifier for each record so that attribute is used as the key value for the index.

<!--- Run the LDAP query --->
<cfldap name="OrgList"
   server="myserver"
   action="query"
   attributes="o, telephonenumber, dn, mail"
   scope="onelevel"
   filter="(|(O=a*) (O=b*))"
   sort="o"
   start="c=US">

<!--- Output query record set --->
<cfoutput query="OrgList">
   DN: #dn# <br>
   O: #o# <br>
   TELEPHONENUMBER: #telephonenumber# <br>
   MAIL: #mail# <br>
=============================<br>
</cfoutput>

<!--- Index the record set --->
<cfindex action="update"
   collection="ldap_query"
   key="dn"
   type="custom"
   title="o"
   query="OrgList"
   body="telephonenumber">

<!--- Search the collection --->
<!--- Use the wildcard * to contain the search string --->
<cfsearch collection="ldap_query"
   name="s_ldap"
   criteria="*617*">

<!--- Output returned records --->
<cfoutput query="s_ldap">
   #Key#, #Title#, #Body# <br>
</cfoutput>


Indexing cfpop query results

The contents of mail servers are generally volatile; specifically, the message number is reset as messages are added and deleted. To avoid mismatches between the unique message number identifiers on the server and in the Verity collection, you must re-index the collection before processing a search.

As with the other query types, you must provide a unique value for the key attribute and enter the data fields to index in the body attribute.

The following example updates the pop_query collection with the current mail for user1, and searches and returns the message number and subject line for all messages containing the word “action”:

<!--- Run POP query --->
<cfpop action="getall"
   name="p_messages"
   server="mail.company.com"
   userName="user1"
   password="user1">

<!--- Output POP query record set --->
<cfoutput query="p_messages">
   #messagenumber# <br>
   #from# <br>
   #to# <br>
   #subject# <br>
   #body# <br>
<hr>
</cfoutput>

<!--- Index record set --->
<cfindex action="update"
   collection="pop_query"
   key="messagenumber"
   type="custom"
   title="subject"
   query="p_messages"
   body="body">

<!--- Search messages for the word "action" --->
<cfsearch collection="pop_query"
   name="s_messages"
   criteria="action">

<!--- Output search record set --->
<cfoutput query="s_messages">
   #key#, #title# <br>
</cfoutput>


Using database-directed indexing

You can use the cfindex tag with a database that contains information on how to construct, or populate, the index. The cfindex tag has a type attribute, which can have custom, file, or path as its value. When type=custom, ColdFusion populates a collection with the contents of the record set. When type=file or type=custom, the record set becomes the input to perform any action--as defined by the action attribute--that uses the key attribute as input for filenames or filepaths.

The following figure shows a database that you can use to populate a collection:

This is a picture of the feature being described.

The following code shows how to populate a collection named snippets with files that are specified in the description column of the database:

<html>
<head>
   <title>Database-directed index population</title>
</head>

<body>

<cfquery name="bookquery"
    datasource="book">
    SELECT * FROM book where bookid='file'
        </cfquery>

<cfoutput query="bookquery">
    #url#,#description# <br>

<cfindex collection="snippets" action="update" type="file" query="bookquery"
key="description" urlpath="url">

</cfoutput>
</body>
</html>

Use the following code to search the snippets collection and display the results:

<cfsearch name="mySearch" collection="snippets" criteria="*.,.*">
<cfdump var="#mySearch#">

The following code shows how to populate the snippets collection with paths that are specified in the description column of the database:

<html>
<cfquery name="bookquery"
    datasource="book">
    SELECT * FROM book where bookid='path1' or bookid='path2'
        </cfquery>

<cfoutput query="bookquery">
    #url#,#description# <br>

<cfindex collection="snippets" action="update" type="path" query="bookquery"
key="description" urlpath="url" >

</cfoutput>
Previous


Using Verity Search Expressions

This chapter describes Verity search expressions and how you can refine your searches to yield the most accurate results.

Contents
  • About Verity query types
  • Using simple queries
  • Using explicit queries
  • Composing search expressions
  • Refining your searches with zones and fields
Next


About Verity query types

When you search a Verity collection, you can use either a simple or explicit query. The following table compares the two types:

Query type
Content
Use of operators and modifiers
CFML example
Simple
One or more words
Uses STEM operator and MANY modifier, by default
<cfsearch name = "band_search"
   collection="bbb"
   type = "simple"
   criteria="film">
Explicit
Words, operators, modifiers
Must be specified
<cfsearch name = "my_search"
   collection="bbb"
   type = "explicit"
criteria="<WILDCARD>'sl[iau]m'">

The query type determines whether the search words that you enter are stemmed, and whether the retrieved words contribute to relevance-ranked scoring. Both of these conditions occur by default in simple queries. For more information on the STEM operator and MANY modifier, see Stemming in simple queries.

Note: Operators and modifiers are formatted as uppercase letters in this chapter solely to enhance legibility. They may be all lowercase or uppercase.


Using simple queries

The simple query is the default query type and is appropriate for the vast majority of searches. When entering text on a search form, you perform a simple query by entering a word or comma-delimited strings, with optional wildcard characters. Verity treats each comma as a logical OR. If you omit the commas, Verity treats the expression as a phrase.

Caution:Many web search engines assume a logical AND for multiple word searches, and search for a phrase only if you use quotation marks. Because Verity treats multiple word searches differently, it might help your users if you provide examples on your search page or a brief explanation of how to search.

The following table shows examples of simple searches:

Example | Search result
low,brass,instrument | low or brass or instrument
low brass instrument | the phrase, low brass instrument
film | film, films, filming, or filmed
filming AND fun | film, films, filming, or filmed, and fun
filming OR fun | film, films, filming, or filmed, or fun
filming NOT fun | film, films, filming, or filmed, but not fun

The operators AND and OR, and the modifier NOT, do not require angle brackets (<>). Operators typically require angle brackets and are used in explicit queries. For more information about operators and modifiers, see .


Stemming in simple queries

By default, Verity interprets words in a simple query as if you entered the STEM operator (and MANY modifier). The STEM operator searches for words that derive from a common stem. For example, a search for instructional returns files that contain instruct, instructs, instructions, and so on.

The STEM operator works on words, not word fragments. A search for instrument returns documents containing instrument, instruments, instrumental, and instrumentation, whereas a search for instru does not. (A wildcard search for instru* returns documents with these words, and also those with instruct, instructional, and so forth.)

Note: The MANY modifier presents the files returned in the search as a list based on a relevancy score. A file with more occurrences of the search word has a higher score than a file with fewer occurrences. As a result, the search engine ranks files according to word density as it searches for the word that you specify, as well as words that have the same stem. For more information on the MANY modifier, see Modifiers.

The following figure shows a basic search interface performing a single word search:

This is a picture of the feature being described.

The results of this search show the effects of the STEM operator and MANY modifier:

This is a picture of the feature being described.

In CFML, enter your search term(s) in the criteria attribute of the cfsearch tag:

<cfsearch name="search_name"
   collection="bbb"
   type="simple"
criteria="instructional">


Preventing stemming

When entering text on a search form, you can prevent Verity from implicitly adding the STEM operator by doing one of the following:

  • Perform an explicit query. For more information, see Using explicit queries.
  • Use the WORD operator. For more information, see Operators.

In CFML, you can prevent stemming by enclosing the double-quoted search term with single quotes:

<cfsearch name="search_name"
   collection="bbb"
   type="simple"
criteria='"instructional"'


Using explicit queries

In an explicit query, the Verity search engine literally interprets your search terms. There are two ways to perform an explicit query:

  • On a search form, use quotation marks around your search term(s).
  • In CFML, use type=explicit in the cfsearch tag.

When you enclose the search term in double quotation marks, Verity does not use the STEM operator. For example, a search for “instructional”--enclosed in quotation marks--does not return files that contain instruct, instructs, instructions, and so on (unless the files also contain instructional). As the following figure shows, this search retrieves fewer files than a search without quotation marks:

This is a picture of the feature being described.


Using AND, OR, and NOT

Verity has many powerful operators and modifiers available for searching (for more information, see Operators and modifiers). However, users might only use the most basic operators--AND and OR, and the modifier NOT. There are a few points to keep in mind:

  • Operators can be typed in upper case or lower case letters.
  • Operators are read from left to right. The AND operator takes precedence over the OR operator.
  • Parentheses can be used to clarify the search. Terms enclosed in parentheses are evaluated first; innermost parentheses are evaluated first when there are nested parentheses.
  • To search for a literal AND, OR, or NOT, enclose the literal term in double quotation marks; for example:
    • love “and” marriage.

Note: Although NOT is a modifier, you use it only with the AND and OR operators. Therefore, it is sometimes casually referred to as an operator.

The following table gives examples of searches and their results:

Search term | Returns files that contain
doctorate AND nausea | both doctorate and nausea
doctorate “and” nausea | the phrase doctorate and nausea
“doctorate and nausea” | the phrase doctorate and nausea
masters OR doctorate AND nausea | masters, or the combination of doctorate and nausea
masters OR (doctorate AND nausea) | masters, or the combination of doctorate and nausea
(masters OR doctorate) AND nausea | either masters or doctorate, and nausea
masters OR doctorate NOT nausea | either masters or doctorate, but not nausea


Using wildcards and special characters

Part of the strength of the Verity search is its use of wildcards and special characters to refine searches. Wildcard searches are especially useful when you are unsure of the correct spelling of a term. Special characters help you search for tags in your code.


Searching with wildcards

The following table shows the wildcard characters that you can use to search Verity collections:

Wildcard | Description | Example | Search result
? | Matches any single alphanumeric character. | apple? | apples or applet
* | Matches zero or more alphanumeric characters. Avoid using the asterisk as the first character in a search string. An asterisk is ignored in a set, ([]) or an alternative pattern ({}). | app*ed | Appleseed, applied, appropriated, and so on.
[ ] | Matches any one of the characters in the brackets. Square brackets indicate an implied OR. | <WILDCARD> 'sl[iau]m' | slim, slam, or slum
{ } | Matches any one of a set of patterns separated by a comma, | <WILDCARD> 'hoist{s,ing,ed}' | hoists, hoisting, or hoisted
^ | Matches any character not in the set. | <WILDCARD>'sl[^ia]m' | slum, but not slim or slam.
- | Specifies a range for a single character in a set. | <WILDCARD> 'c[a-r]t' | cat, cot, but not cut (that is, every word beginning with c, ending with t, and containing any single letter from a to r)

To search for a wildcard character as a literal, place a backslash before it; for example:

  • To match a question mark or other wildcard character, precede the ? with one backslash. For example, type the following in a search form: Checkers\?
  • To match a literal asterisk, you precede the * with two backslashes, and enclose the search term with either single or double quotation marks. For example, type the following in a search form: ’M\\*’ (or “M\\*”) This is the corresponding CFML code:
    • <cfsearch name = "quick_search"
   collection="bbb"
   type = "simple"
   criteria="'M\\*'">

    Note: The last line is equivalent to criteria=’”M\\*”’>.


Searching for special characters

The search engine handles a number of characters in particular ways as the following table describes:

Characters | Description
, ( ) [ | These characters end a text token. A token is a variable that stores configurable properties. It lets the administrator or user configure various settings and options.
= > < ! | These characters also end a text token. They are terminated by an associated end character.
' ` < { [ ! | These characters signify the start of a delimited token. They are terminated by an associated end character.

To search for special characters as literals, precede the following nonalphanumeric characters with a backslash character (\) in a search string:

  • comma (,)
  • left and right parentheses ()
  • double quotation mark (")
  • backslash (\)
  • left curly brace ({)
  • left bracket ([)
  • less than sign (<)
  • backquote (`)

In addition to the backslash character, you can use paired backquotes (` `) to interpret special characters as literals. For example, to search for the wildcard string “a{b” you can surround the string with backquotes, as follows:

`a{b`

To search for a wildcard string that includes the literal backquote character (`) you must use two backquotes together and surround the entire string in backquotes:

`*n``t`

You can use paired backquotes or backslashes to escape special characters. There is no functional difference between the two. For example, you can query for the term: <DDA> using \<DDA\> or `<DDA>` as your search term.


Composing search expressions

The following rules apply to the composition of search expressions.


Case sensitivity

Verity searches are case-sensitive only when the search term is entered in mixed case. For example, a search for zeus finds zeus, Zeus, or ZEUS; however, a search for Zeus finds only Zeus.

To have your application always ignore the case the user types, use the LCase function in the criteria attribute of cfsearch. The following code converts user input to lowercase, thereby eliminating case-sensitivity concerns:

<cfsearch name="results"
   collection="#form.collname#"
   criteria="#LCase(form.criteria)#"
   type="#form.type#">


Prefix and infix notation

By default, Verity uses infix notation, in which precedence is implicit in the expression; for example, the AND operator takes precedence over the OR operator.

You can use prefix notation with any operator except an evidence operator (typically, STEM, WILDCARD, or WORD; for a description of evidence operators, see ). In prefix notation, the expression explicitly specifies precedence. Rather than repeating an operator, you can use prefix notation to list the operator once and list the search targets in parentheses. For example, these expressions are equivalent:

  • Moses <NEAR> Larry <NEAR> Jerome <NEAR> Daniel <NEAR> Jacob
  • <NEAR>(Moses,Larry,Jerome,Daniel,Jacob)

The following prefix notation example searches first for documents that contain Larry and Jerome, then for documents that contain Moses:

  • OR (Moses, AND (Larry,Jerome))

The infix notation equivalent of this is as follows:

  • Moses OR (Larry AND Jerome)


Commas in expressions

If an expression includes two or more search terms within parentheses, a comma is required between the elements (whitespace is ignored). The following example searches for documents that contain any combination of Larry and Jerome together:

  • AND (Larry, Jerome)


Precedence rules

Expressions are read from left to right. The AND operator takes precedence over the OR operator; however, terms enclosed in parentheses are evaluated first. When the search engine encounters nested parentheses, it starts with the innermost term.

Example | Search result
Moses AND Larry OR Jerome | documents that contain Moses and Larry, or Jerome
(Moses AND Larry) OR Jerome | (same as above)
Moses AND (Larry OR Jerome) | documents that contain Moses and either Larry or Jerome


Delimiters in expressions

You use angle brackets (< >), double quotation marks ("), and backslashes (\) to delimit various elements in a search expression, as the following table describes:

Character | Usage
< > | Left and right angle brackets are reserved for designating operators and modifiers. They are optional for the AND, OR, and NOT, but required for all other operators.
" | Use double quotation marks in expressions to search for a word that is otherwise reserved as an operator or modifier, such as AND, OR, and NOT.
\ | To include a backslash in a search expression, insert two backslashes for each backslash character that you want included in the search; for example, C:\\cfusionmx\\bin.


Operators and modifiers

You are probably familiar with searches containing AND, OR, and NOT. Verity has many additional operators and modifiers, of various types, that offer you a high degree of specificity in setting search parameters.


Operators

An operator represents logic to be applied to a search element. This logic defines the qualifications that a document must meet to be retrieved. You can use operators to refine your search or to influence the results in other ways.

For example, you can construct an HTML form for conducting searches. In the form, you can search for a single term. You can refine the search by limiting the search scope in a number of ways. Operators are available for limiting a query to a sentence or paragraph, and you can search words based on proximity.

Ordinarily, you use operators in explicit searches as follows:

"<operator>search_string"

The following operator types are available:

Operator type | Purpose
Concept | Identifies a concept in a document by combining the meanings of search elements.
Relational | Searches fields in a collection.
Evidence | Specifies basic and intelligent word searches.
Proximity | Specifies the relative location of words in a document.
Score | Manipulates the score returned by a search element. You can set the score percentage display to four decimal places.

The following table shows the operators, according to type, that are available for conducting searches of ColdFusion Verity collections:

Concept | Relational | Evidence | Proximity | Score
ACCRUE | < | STEM | NEAR | YESNO
ALL | <= | WILDCARD | NEAR/N | PRODUCT
AND | = | WORD | PARAGRAPH | SUM
ANY | > | THESAURUS | PHRASE | COMPLEMENT
OR | >= | SOUNDEX | SENTENCE |
 | CONTAINS | TYPO/N | IN |
 | MATCHES |  |  |
 | STARTS |  |  |
 | ENDS |  |  |
 | SUBSTRING |  |  |


Concept operators

Concept operators combine the meaning of search elements to identify a concept in a document. Documents retrieved using concept operators are ranked by relevance. The following table describes each concept operator:

Operator | Description
AND | Selects documents that contain all the search elements that you specify.
OR | Selects documents that show evidence of at least one of the search elements that you specify.
ACCRUE | Selects documents that include at least one of the search elements that you specify. Documents are ranked based on the number of search elements found.
ALL | Selects documents that contain all of the search elements that you specify. A score of 1.00 is assigned to each retrieved document. ALL and AND retrieve the same results, but queries using ALL are always assigned a score of 1.00.
ANY | Selects documents that contain at least one of the search elements that you specify. A score of 1.00 is assigned to each retrieved document. ANY and OR retrieve the same results, but queries using ANY are always assigned a score of 1.00.


Relational operators

Relational operators search document fields (such as AUTHOR) that you defined in the collection. Documents containing specified field values are returned. Documents retrieved using relational operators are not ranked by relevance, and you cannot use the MANY modifier with relational operators.

You use the following operators for numeric and date comparisons:

Operator | Description
= | Equal
!= | Not equal
> | Greater than
>= | Greater than or equal to
< | Less than
<= | Less than or equal to

For example, to search for documents that contain values for 1999 through 2002, you could perform either of the following searches:

  • a simple search for 1999,2000,2001,2002
  • an explicit search using the = operator: >=1999,<=2002

If a document field named PAGES is defined, you can search for documents that are 5 pages or less by entering PAGES < 5 in your search. Similarly, if a document field named DATE is defined, you can search for documents dated prior to and including December 31, 1999 by entering DATE <= 12-31-99 in your search.

The following relational operators compare text and match words and parts of words:

Operator
Description
Example
CONTAINS
Selects documents by matching the word or phrase that you specify with the values stored in a specific document field. Documents are selected only if the search elements specified appear in the same sequential and contiguous order in the field value.
  • In a document field named TITLE, to retrieve documents whose titles contain music, musical, or musician, search for TITLE <CONTAINS> Musi*.
  • To retrieve CFML and HTML pages whose meta tags contain Framingham as a content word, search for KEYWORD <CONTAINS> Framingham.
MATCHES
Selects documents by matching the query string with values stored in a specific document field. Documents are selected only if the search elements specified match the field value exactly. If a partial match is found, a document is not selected. When you use the MATCHES operator, you specify the field name to search, and the word, phrase, or number to locate. You can use ? and * to represent individual and multiple characters, respectively, within a string.
See the text immediately after this table for examples.
STARTS
Selects documents by matching the character string that you specify with the starting characters of the values stored in a specific document field.
In a document field named REPORTER, to retrieve documents written by Clark, Clarks, and Clarkson, search for REPORTER <STARTS> Clark.
ENDS
Selects documents by matching the character string that you specify with the ending characters of the values stored in a specific document field.
In a document field named OFFICER, to retrieve arrest reports written by Tanner, Garner, and Milner, search for OFFICER <ENDS> ner.
SUBSTRING
Selects documents by matching the query string that you specify with any portion of the strings in a specific document field.
In a document field named TITLE, to retrieve documents whose titles contain words such as solution, resolution, solve, and resolve, search for TITLE <SUBSTRING> sol.

For example, assume a document field named SOURCE includes the following values:

  • Computer
  • Computerworld
  • Computer Currents
  • PC Computing

To locate documents whose source is Computer, enter the following:

  • SOURCE <MATCHES> computer

To locate documents whose source is Computer, Computerworld, and Computer Currents, enter the following:

  • SOURCE <MATCHES> computer*

To locate documents whose source is Computer, Computerworld, Computer Currents, and PC Computing, enter the following:

SOURCE <MATCHES> *comput*

For an example of ColdFusion code that uses the CONTAINS relational operator, see .

You can use the SUBSTRING operator to match a character string with data stored in a specified data source. In the example described in this section, a data source called TEST1 contains the table YearPlaceText, which contains three columns: Year, Place, and Text. Year and Place make up the primary key. The following table shows the TEST1 schema:

Year | Place | Text
1990 | Utah | Text about Utah 1990
1990 | Oregon | Text about Oregon 1990
1991 | Utah | Text about Utah 1991
1991 | Oregon | Text about Oregon 1991
1992 | Utah | Text about Utah 1992

The following application page matches records that have 1990 in the TEXT column and are in the Place Utah. The search operates on the collection that contains the TEXT column and then narrows further by searching for the string “Utah” in the CF_TITLE document field. Document fields are defaults defined in every collection corresponding to the values that you define for URL, TITLE, and KEY in the cfindex tag.

<cfquery name="GetText"
   datasource="TEST1">
   SELECT Year+Place AS Identifier, text
      FROM YearPlaceText
</cfquery>

<cfindex collection="testcollection"
   action="Update"
   type="Custom"
   title="Identifier"
   key="Identifier"
   body="TEXT"
   query="GetText">

<cfsearch name="GetText_Search"
   collection="testcollection"
   type="Explicit"
   criteria="1990 and CF_TITLE <SUBSTRING> Utah">
<cfoutput>
   Record Counts: <br>
   #GetText.RecordCount# <br>
   #GetText_Search.RecordCount# <br>
</cfoutput>

Query Results --- Should be 5 rows <br>
<cfoutput query="Gettext">
   #Identifier# <br>
</cfoutput>

Search Results -- should be 1 row <br>
<cfoutput query="GetText_Search">
   #GetText_Search.TITLE# <br>
</cfoutput>


Evidence operators

Evidence operators let you specify a basic word search or an intelligent word search. A basic word search finds documents that contain only the word or words specified in the query. An intelligent word search expands the query terms to create an expanded word list so that the search returns documents that contain variations of the query terms.

Documents retrieved using evidence operators are not ranked by relevance unless you use the MANY modifier.

The following table describes the evidence operators:

Operator | Description | Example
STEM | Expands the search to include the word that you enter and its variations. The STEM operator is automatically implied in any simple query. | <STEM>believe retrieves matches such as “believe,” “believing,” and “believer”.
WILDCARD | Matches wildcard characters included in search strings. Certain characters automatically indicate a wildcard specification, such as apostrophe (*) and question mark(?). | spam* retrieves matches such as, spam, spammer, and spamming.
WORD | Performs a basic word search, selecting documents that include one or more instances of the specific word that you enter. The WORD operator is automatically implied in any SIMPLE query. | <WORD> logic retrieves logic, but not variations such as logical and logician.
THESAURUS | Expands the search to include the word that you enter and its synonyms. Collections do not have a thesaurus by default; to use this feature you must build one. | <THESAURUS> altitude retrieves documents containing synonyms of the word altitude, such as height or elevation.
SOUNDEX | Expands the search to include the word that you enter and one or more words that “sound like,” or whose letter pattern is similar to, the word specified. Collections do not have sound-alike indexes by default; to use this feature you must build sound-alike indexes. | <SOUNDEX> sale retrieves words such as sale, sell, seal, shell, soul, and scale.
TYPO/N | Expands the search to include the word that you enter plus words that are similar to the query term. This operator performs “approximate pattern matching” to identify similar words. The optional N variable in the operator name expresses the maximum number of errors between the query term and a matched term, a value called the error distance. If N is not specified, the default error distance is 2. | <TYPO> swept retrieves kept.

The following example uses an evidence operator:

<cfsearch name = "quick_search"
   collection="bbb"
   type = "explicit"
   criteria="<WORD>film">


Proximity operators

Proximity operators specify the relative location of specific words in the document. To retrieve a document, the specified words must be in the same phrase, paragraph, or sentence. In the case of NEAR and NEAR/N operators, retrieved documents are ranked by relevance based on the proximity of the specified words. Proximity operators can be nested; phrases or words can appear within SENTENCE or PARAGRAPH operators, and SENTENCE operators can appear within PARAGRAPH operators.

The following table describes the proximity operators:

Operator
Description
Example
NEAR
Selects documents containing specified search terms. The closer the search terms are to one another within a document, the higher the document’s score. The document with the smallest possible region containing all search terms always receives the highest score. Documents whose search terms are not within 1000 words of each other are not selected.
war <NEAR> peace retrieves documents that contain stemmed variations of these words within close proximity to each other (as defined by Verity). To control search proximity, use NEAR/N.
NEAR/N
Selects documents containing two or more search terms within N number of words of each other, where N is an integer between 1 and 1024. NEAR/1 searches for two words that are next to each other. The closer the search terms are within a document, the higher the document's score.
You can specify multiple search terms using multiple instances of NEAR/N as long as the value of N is the same.
commute <NEAR/10> bicycle <NEAR/10> train <NEAR/10> retrieves documents that contain stemmed variations of these words within 10 words of each other.
PARAGRAPH
Selects documents that include all of the words you specify within the same paragraph. To search for three or more words or phrases in a paragraph, you must use the PARAGRAPH operator between each word or phrase.
<PARAGRAPH> (mission, goal, statement) retrieves documents that contain these terms within a paragraph.
PHRASE
Selects documents that include a phrase you specify. A phrase is a grouping of two or more words that occur in a specific order.
<PHRASE> (mission, oak) returns documents that contain the phrase mission oak.
SENTENCE
Selects documents that include all of the words you specify within the same sentence.
<SENTENCE> (jazz, musician) returns documents that contain these words in the same sentence.
IN
Selects documents that contain specified values in one or more document zones. A document zone represents a region of a document, such as the document’s summary, date, or body text. To search for a term only within the one or more zones that have certain conditions, you qualify the IN operator with the WHEN operator.
Chang <IN> author searches document zones named author for the word Chang.

The following example uses a proximity operator:

<cfsearch name = "quick_search"
   collection="bbb"
   type = "explicit"
   criteria="red<near>socks">

For an example using the IN proximity operator to search XML documents , see .


Score operators

Score operators control how the search engine calculates scores for retrieved documents. The maximum score that a returned search element can have is 1.000. You can set the score to display a maximum of four decimal places.

When you use a score operator, the search engine first calculates a separate score for each search element found in a document, and then performs a mathematical operation on the individual element scores to arrive at the final score for each document.

The document’s score is available as a result column. You can use the SCORE result column to get the relevancy score of any document retrieved; for example:

<cfoutput>
   <a href="#Search1.URL#">#Search1.Title#</a><br>
   Document Score=#Search1.SCORE#<BR>
</cfoutput>

The following table describes the score operators:

Operator | Description | Example
YESNO | Forces the score of an element to 1 if the element’s score is nonzero. | <YESNO>mainframe. If the retrieval result of the search on mainframe is 0.75, the YESNO operator forces the result to 1. You can use YESNO to avoid relevance ranking.
PRODUCT | Multiplies the scores for the search elements in each document matching a query. | <PRODUCT>(computers, laptops) takes the product of the resulting scores.
SUM | Adds the scores for the search element in each document matching a query, up to a maximum value of 1. | <SUM>(computers, laptops) takes the sum of the resulting scores.
COMPLEMENT | Calculates scores for documents matching a query by taking the complement (subtracting from 1) of the scores for the query’s search elements. The new score is 1 minus the search element’s original score. | <COMPLEMENT>computers. If the search element’s original score is .785, the COMPLEMENT operator recalculates the score as .215.


Modifiers

You combine modifiers with operators to change the standard behavior of an operator in some way. The following table describes the available modifiers:

Modifier
Description
Example
CASE
Specifies a case-sensitive search. Normally, Verity searches are case-insensitive for search text entered in all uppercase or all lowercase, and case-sensitive for mixed-case search strings.
<CASE>Java OR <CASE>java retrieves documents that contain Java or java, but not JAVA.
MANY
Counts the density of words, stemmed variations, or phrases in a document and produces a relevance-ranked score for retrieved documents. Use with the following operators:
  • WORD
  • WILDCARD
  • STEM
  • PHRASE
  • SENTENCE
  • PARAGRAPH
<PARAGRAPH><MANY>javascript <AND> vbscript.
You cannot use the MANY modifier with the following operators:
  • AND
  • OR
  • ACCRUE
  • Relational operators
NOT
Excludes documents that contain the specified word or phrase. Use only with the AND and OR operators.
Java <AND> programming <NOT> coffee retrieves documents that contain Java and programming, but not coffee.
ORDER
Specifies that the search elements must occur in the same order in which you specify them in the query. Use with the following operators:
  • PARAGRAPH
  • SENTENCE
  • NEAR/N
Place the ORDER modifier before any operator.
<ORDER><PARAGRAPH> ("server", "Java") retrieves documents that contain server before Java.


Refining your searches with zones and fields

One of the strengths of Verity is its ability to perform full-text searches on documents of many formats. However, there are often times when you want to restrict a search to certain portions of a document, to improve search relevance. If a Verity collection contains some documents about baseball and other documents about caves, then a search for the word bat may retrieve several irrelevant results.

If the documents are structured documents, you can take advantage of the ability to search zones and fields. The following are some examples of structured documents:

  • Documents created with markup languages (XML, SGML, HTML)
  • Internet Message Format documents
  • Documents created by many popular word-processing applications

Note: Although your word processor may open with what appears to be a blank page, the document has many regions such as title, subject, and author. Refer to your application’s documentation or online help system for how to view a document’s properties.


Zone searches

You can perform zone searches on markup language documents. The Verity zone filter includes built-in support for HTML and several file formats; for a list of supported file formats, see Building a Search Interface. Verity searches XML files by treating the XML tags as zones. When you use the zone filter, the Verity engine builds zone information into the collection’s full-word index. This index, enhanced with zone information, permits quick and efficient searches over zones. The zone filter can automatically define a zone, or you can define it yourself in the style.zon file. You can use zone searching to limit your search to a particular zone. This can produce more accurate, but not necessarily faster, search results than searching an entire file.

Note: The contents of a zone cannot be returned in the results list of an application.


Examples

The following examples perform zone searching on XML files. In a list of rock bands, you could have XML files with tags for the instruments and for comments. In the following XML file, the word Pete appears in a comment field:

<band.xml>
    <Lead_Guitar>Dan</Lead_Guitar>
    <Rhythm_Guitar>Jake</Rhythm_Guitar>
    <Bass_Guitar>Mike</Bass_Guitar>
    <Drums>Chris</Drums>
    <COMMENT_A>Dan plays guitar, better than Pete.</COMMENT_A>
    <COMMENT_B>Jake plays rhythm guitar.</COMMENT_B>
</band.xml>

The following CFML code shows a search for the word Pete:

<cfsearch name = "band_search"
   collection="my_collection"
   type = "simple"
criteria=”Pete”>

The above search for Pete returns this XML file because this search target is in the COMMENT_A field. In contrast, Pete is the lead guitarist in the following XML file:

<band.xml>
    <Lead_Guitar>Pete</Lead_Guitar>
    <Rhythm_Guitar>Roger</Rhythm_Guitar>
   <Bass_Guitar>John</Bass_Guitar>
    <Drums>Kenny</Drums>
    <COMMENT_A>Who knows who's better than this band?</COMMENT_A>
    <COMMENT_B>Ticket prices correlated with decibels.</COMMENT_B>
</band.xml>

To retrieve only the files in which Pete is the lead guitarist, perform a zone search using the IN operator according to the following syntax:

(query) <IN> (zone1, zone2, ...)

Note: As with other operators, IN may be uppercase or lowercase. Unlike AND, OR, or NOT, you must enclose IN within brackets.

Thus, the following explicit search retrieves files in which Pete is the lead guitarist:

(Pete) <in> Lead_Guitar

This is expressed in CFML as:

<cfsearch name = "band_search"
   collection="my_collection"
   type = "explicit"
   criteria="(Pete) <in> Lead_Guitar">

To retrieve files in which Pete plays either lead or rhythm guitar, use the following explicit search:

(Pete) <in> (Lead_Guitar,Rhythm_Guitar)

This is expressed in CFML as:

<cfsearch name = "band_search"
   collection="bbb"
   type = "explicit"
   criteria="(Pete) <in> (Lead_Guitar,Rhythm_Guitar)">


Field searches

Fields are extracted from the document and stored in the collection for retrieval and searching, and can be returned on a results list. Zones, on the other hand, are merely the definitions of “regions” of a document for searching purposes, and are not physically extracted from the document in the same way that fields are extracted.

You must define a region of text as a zone before it can be a field. Therefore, it can be only a zone, or it can be both a field and a zone. Whether you define a region of text as a zone only or as both a field and a zone depends on your particular requirements.

A field must be defined in the style file, style.ufl, before you create the collection. To map zones to fields (to display field data), you must define and add these extra fields to style.ufl.

You can specify the values for the cfindex attributes TITLE, KEY, URL, and CUSTOM as document fields for use with relational operators in the criteria attribute. (The SCORE and SUMMARY attributes are automatically returned by a cfsearch; these attributes are different for each record of a collection as the search criteria changes.) Text comparison operators can reference the following document fields:

  • cf_title
  • cf_key
  • cf_url
  • cf_custom1
  • cf_custom2

To explore how to use document fields to refine a search, consider the following database table, named Calls. This table has four fields and three records, as shown below:

call_ID | Problem_Description | Short_Description | Product
1 | Can't bold text properly under certain conditions | Bold Problem | HomeSite
2 | Certain optional attributes are acting as required attributes | Attributes Problem | ColdFusion
3 | Can’t do a File/Open in certain cases | File Open Problem | HomeSite

A Verity search for the word certain returns three records. However, you can use the document fields to restrict your search; for example, a search to retrieve HomeSite problems with the word certain in the problem description.

These are the requirements to run this procedure:

  • Create and populate the Calls table in a database of your choice
  • Create a collection named Training (you can do this in CFML or in the ColdFusion Administrator).

The following table shows the relationship between database column and cfindex attribute:

Database column | cfindex attribute | Comment
call_ID | key | The primary key of a database table is often a key attribute.
Problem_Description | body | This column is the information to be indexed.
Short_Description | title | A short description is conceptually equivalent to a title, as in a running title of a journal article.
Product | custom1 | This field refines the search.

You begin by selecting all data in a query:

<cfquery name = "Calls" datasource = "MyDSN">
   Select * from Calls
</cfquery>

The following code shows the cfindex tag for indexing the collection (the type attribute is set to custom for tablular data):

<cfindex
   query = "Calls"
   collection = "training"
   action = "UPDATE"
   type = "CUSTOM"
   title = "Short_Description"
   key = "Call_ID"
   body = "Problem_Description"
   custom1 = "Product">

To perform the refined search for HomeSite problems with the word certain in the problem description, the cfsearch tag uses the CONTAINS operator in its criteria attribute:

<cfsearch
   collection = "training"
   name = "search_calls"
   criteria = "certain and CF_CUSTOM1 <CONTAINS> HomeSite">

The following code displays the results of the refined search:

<table border="1" cellspacing="5">
<tr>
   <th align="LEFT">KEY</th>
   <th align="LEFT">TITLE</th>
   <th align="LEFT">CUSTOM1</th>
</tr>

<cfoutput query = "search_calls">
<tr>
   <td>#KEY#</td>
   <td>#TITLE#</td>
   <td>#CUSTOM1#</td>
</tr>
</cfoutput>
</table>

In a browser, the retrieved results appear:

This is a picture of the feature being described.

Previous


Retrieving and Formatting Data

This chapter explains how to use HTML forms to control the data displayed by a dynamic Web page. It also describes how to populate an HTML table with query results and how to use ColdFusion functions to format and manipulate data.

Contents
  • Using forms to specify the data to retrieve
  • Working with Action Pages
  • Working with queries and data
  • Returning results to the user
  • Dynamically populating list boxes
  • Creating dynamic check boxes and multiple-selection list boxes
  • Validating form field data types
Next


Using forms to specify the data to retrieve

In the examples in previous chapters, you retrieved all of the records from a database table using a SQL query. However, there are many instances when you want to retrieve data based on certain criteria. For example, you might want to retrieve records for everyone in a particular department, everyone in a particular town whose last name is Smith, or books by a certain author.

You can use forms in ColdFusion applications to allow users to specify what data they retrieve in a query. When you submit a form, you pass the variables to an associated page, called an action page, where some type of processing takes place.

The following figure shows a form, defined by FormPage.cfm, and its associated action page, ActionPage.cfm:

This is a picture of the feature being described.

Note: Because forms are standard HTML, the syntax and examples that follow provide you with just enough detail to begin using ColdFusion. For information on using ColdFusion forms defined by the cfform tag, see Building Dynamic Forms.


HTML form tag syntax

Use the following syntax for the HTML form tag:

<form action="actionpage.cfm" method="post">
   ...
</form>

Attribute

Description

action

Specifies an action page to which you pass form variables for processing.

method

Specifies how the variables are submitted from the browser to the action page on the server. All ColdFusion forms must be submitted with an attribute setting of method=“post”.

You can override the server request timeout (set on the ColdFusion Administrator Server Settings page) by adding a RequestTimeout parameter to the action page URL. Requests that take longer than the specified time are terminated. The following example specifies a request time-out of two minutes:

<form name="getReportCriteria"
      action="runReport.cfm?RequestTimeout=120" method="post">


Form controls

Within the form, you describe the form controls needed to gather and submit user input. There are a variety of form controls types available. You select form control input types based on the type input you want to user to provide.

The following figure shows an example form containing different form controls:

This is a picture of the feature being described.

The following table shows the format of form control tags:

Control
Code
Text control
<input type="Text" name="ControlName" size="Value" maxlength="Value">
Radio buttons
<input type="Radio" name="ControlName" value="Value1">DisplayName1
<input type="Radio" name="ControlName" value="Value2">DisplayName2
<input type="Radio" name="ControlName" value="Value3">DisplayName3
List box
<select name="ControlName">
   <option value="Value1">DisplayName1
   <option value="Value2">DisplayName2
   <option value="Value3">DisplayName3
</select>
Check box
<input type="Checkbox" name="ControlName" value="Yes|No">Yes
Reset button
<input type="Reset" name="ControlName" value="DisplayName">
Submit button
<input type="Submit" name="ControlName" value="DisplayName">

Use the following procedure to create the form in the previous figure.

To create a form:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Input form</title>
</head>
<body>
<!--- define the action page in the form tag. The form variables will
      pass to this page when the form is submitted --->

<form action="actionpage.cfm" method="post">

<!-- text box -->
<p>
First Name: <input type="Text" name="FirstName" size="20"
maxlength="35"><br>
Last Name: <input type="Text" name="LastName" size="20"
maxlength="35"><br>
Salary: <input type="Text" name="Salary" size="10" maxlength="10">
</p>

<!-- list box -->
<p>
City
<select name="City">
   <option value="Arlington">Arlington
   <option value="Boston">Boston
   <option value="Cambridge">Cambridge
   <option value="Minneapolis">Minneapolis
   <option value="Seattle">Seattle
</select>
</p>

<!-- radio buttons -->
<p>
Department:<br>
<input type="radio" name="Department" value="Training">Training<br>
<input type="radio" name="Department" value="Sales">Sales<br>
<input type="radio" name="Department"
value="Marketing">Marketing<br>
</p>

<!-- check box -->
<p>
Contractor? <input type="checkbox" name="Contractor"
value="Yes" checked>Yes
</p>

<!-- reset button -->
<input type="Reset" name="ResetForm" value="Clear Form">
<!-- submit button -->
<input type="Submit" name="SubmitForm" value="Submit">

</form>
</body>
</html>
  2. Save the page as formpage.cfm within the myapps directory under your Web root directory.
  3. View the form in a browser.

    4. The form appears in the browser.

    Don’t click the Submit button yet. Remember that you need an action page in order to submit values; you create one later in this chapter in Creating action pages.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<form action="actionpage.cfm"
   method="post">
Gathers the information from this form using the Post method, and do something with it on the page actionpage.cfm.
<input type="Text" name="FirstName"
   size="20" maxlength="35">
Creates a text box called FirstName where users can enter their first name. Makes it 20 characters wide, but allows input of up to 35 characters.
<input type="Text" name="LastName"
   size="20" maxlength="35">
Creates a text box called LastName where users can enter their first name. Makes it 20 characters wide, but allows input of up to 35 characters.
<input type="Text" name="Salary"
   size="10" maxlength="10">
Creates a text box called Salary where users can enter a salary to look for. Makes it 10 characters wide, and allows input of up to 10 characters.
<select name="City">
   <option value="Arlington">
      Arlington
   <option value="Boston">Boston
   <option value="Cambridge">
      Cambridge
   <option value="Minneapolis">
      Minneapolis
   <option value="Seattle">Seattle
</select>
Creates a drop-down list box named City and populate it with the values “Arlington,” “Boston,” “Cambridge,” “Minneapolis,” and “Seattle.”
<input type="checkbox" name=
   "Contractor" value="Yes" checked>Yes
Creates a check box that allows users to specify whether they want to list employees who are contractors. Box selected by default.
<input type="Reset"
   name="ResetForm"
   value="Clear Form">
Creates a reset button to allow users to clear the form. Puts the text Clear Form on the button.
<input type="Submit"
   name="SubmitForm"
   value="Submit">
Creates a submit button to send the values that users enter to the action page for processing. Puts the text Submit on the button.


Form notes and considerations

When using forms, keep the following guidelines in mind:

  • To make the coding process easy to follow, name form controls the same as target database fields.
  • For ease of use, limit radio buttons to between three and five mutually exclusive options. If you need more options, consider a drop-down list.
  • Use list boxes to allow the user to choose from many options or to chose multiple items from a list.
  • All the data that you collect on a form is automatically passed as form variables to the associated action page.
  • Check boxes, radio buttons, and multiple select boxes do not pass to action pages unless they are selected on a form. If you try to reference these variables on the action page, you receive an error if they are not present. For information on how to determine if a variable exists on the action page, see Testing for a variable's existence.
  • You can dynamically populate drop-down lists using query data. For more information, see Dynamically populating list boxes.


Working with Action Pages

A ColdFusion action page is just like any other application page except that you can use the form variables that are passed to it from an associated form. The following sections describe how to create effective action pages.


Processing form variables on action pages

The action page gets a form variable for every form control that contains a value when the form is submitted.

Note: If multiple controls have the same name, one form variable is passed to the action page with a comma-delimited list of values.

A form variable's name is the name that you assigned to the form control on the form page. Refer to the form variable by name within tags, functions, and other expressions on an action page.

Because form variables extend beyond the local page--their scope is the action page--prefix them with “Form.” to explicitly tell ColdFusion that you are referring to a form variable. For example, the following code references the LastName form variable for output on an action page:

<cfoutput>
   #Form.LastName#
</cfoutput>

The Form scope also contains a list variable called Form.fieldnames. It contains a list of all form variables submitted to the action page. If no form variables are passed to the action page, ColdFusion does not create the Form.filednames list.


Dynamically generating SQL statements

As described in previous chapters, you can retrieve a record for every employee in a database table by composing a query like this:

<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT  FirstName, LastName, Contract
   FROM   Employee
</cfquery>

But when you want to return information about employees that matches user search criteria, you use the SQL WHERE clause with a SQL SELECT statement. When the WHERE clause is processed, it filters the query data based on the results of the comparison.

For example, to return employee data for only employees with the last name of Smith, you build a query that looks like this:

<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName, Contract
   FROM    Employee
   WHERE  LastName = 'Smith'
</cfquery>

However, instead of putting the LastName directly in the SQL WHERE clause, you can use the text that the user entered in the form for comparison:

<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary
   FROM Employee
   WHERE LastName=<cfqueryparam value="#Form.LastName#"
CFSQLType="CF_SQL_VARCHAR">
</cfquery>

For security, this example encapsulates the form variable within the cfqueryparam tag to ensure that the user passed a valid string value for the LastName. For more information on using the cfqueryparam tag with queries, see Accessing and Retrieving Data.

For more information on Dynamic SQL, see Accessing and Retrieving Data.


Creating action pages

Use the following procedure to create an action page for the page formpage.cfm that you created in the previous example.

To create an action page for the form:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>Retrieving Employee Data Based on Criteria from Form</title>
</head>

<body>
<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary
   FROM Employee
   WHERE LastName=<cfqueryparam value="#Form.LastName#"
CFSQLType="CF_SQL_VARCHAR">
</cfquery>
<h4>Employee Data Based on Criteria from Form</h4>
<cfoutput query="GetEmployees">
#FirstName#
#LastName#
#Salary#<br>
</cfoutput>
<br>
<cfoutput>Contractor: #Form.Contractor#</cfoutput>
</body>
</html>
  2. Save the page as actionpage.cfm within the myapps directory.
  3. View formpage.cfm in your browser.
  4. Enter data, for example, Smith, in the Last Name box and submit the form.

    5. The browser displays a line with the first and last name and salary for each entry in the database that match the name you typed, followed by a line with the text “Contractor: Yes”

  5. Click Back in your browser to redisplay the form.
  6. Remove the check mark from the check box and submit the form again.

    7. This time an error occurs because the check box does not pass a variable to the action page. For information on modifying actionpage.cfm to fix the error, see Testing for a variable's existence.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cfquery name="GetEmployees"
datasource="CompanyInfo">
Queries the data source CompanyInfo and names the query GetEmployees.
SELECT FirstName, LastName, Salary
FROM Employee
WHERE LastName=<cfqueryparam
   value="#Form.LastName#"
   CFSQLType="CF_SQL_VARCHAR">
Retrieves the FirstName, LastName, and Salary fields from the Employee table, but only if the value of the LastName field matches what the user entered in the LastName text box in the form on formpage.cfm.
<cfoutput query="GetEmployees">
Displays results of the GetEmployees query.
#FirstName#
#LastName#
#Salary#<br>
Displays the value of the FirstName, LastName, and Salary fields for a record, starting with the first record, then goes to the next line. Keeps displaying the records that match the criteria you specified in the SELECT statement, followed by a line break, until you run out of records.
</cfoutput>
Closes the cfoutput block.
<br>
<cfoutput>Contractor: #Form.Contractor#
</cfoutput>
Displays a blank line followed by the text Contractor: and the value of the form Contractor check box.
A more complete example would test to ensure the existence of the variable and would use the variable in the query.


Testing for a variable's existence

Before relying on a variable’s existence in an application page, you can test to see if it exists using the ColdFusion IsDefined function. A function is a named procedure that takes input and operates on it. For example, the IsDefined function determines whether a variable exists. CFML provides a large number of functions, which are documented in the CFML Reference.

The following code prevents the error in the previous example by checking to see if the Contractor Form variable exists before using it:

<cfif IsDefined("Form.Contractor")>
<cfoutput>Contractor: #Form.Contractor#</cfoutput>
</cfif>

The argument passed to the IsDefined function must always be enclosed in double quotes. For more information on the IsDefined function, see the CFML Reference.

If you attempt to evaluate a variable that you did not define, ColdFusion cannot process the page and displays an error message. To help diagnose such problems, turn on debugging in the ColdFusion Administrator. The Administrator debugging information shows which variables are being passed to your application pages.


Requiring users to enter values in form fields

One of the limitations of HTML forms is the inability to define input fields as required. Because this is a particularly important requirement for database applications, ColdFusion provides a server-side mechanism for requiring users to enter data in fields.

To require entry in an input field, use a hidden field that has a name attribute composed of the field name and the suffix "_required." For example, to require that the user enter a value in the FirstName field, use the syntax:

<input type="hidden" name="FirstName_required">

If the user leaves the FirstName field empty, ColdFusion rejects the form submittal and returns a message informing the user that the field is required. You can customize the contents of this error message using the value attribute of the hidden field. For example, if you want the error message to read “You must enter your first name,” use the following syntax:

<input type="hidden"
   name="FirstName_required"
   value="You must enter your first name.">


Form variable notes and considerations

When using form variables, keep the following guidelines in mind:

  • A form variable's scope is the action page.
  • Prefix form variables with "Form." when referencing them on the action page.
  • Surround variable values with pound signs (#) for output.
  • Variables for check boxes, radio buttons, and multiple select list boxes only get passed to the action page if you select an option. Text boxes, passwords, and textareas pass an empty string if you do not enter text.
  • An error occurs if the action page tries to use a variable that was not passed.
  • If multiple controls have the same name, one form variable is passed to the action page with a comma-delimited list of values.


Working with queries and data

The ability to generate and display query data is one of the most important and flexible features of ColdFusion. The following sections describe more about using queries and displaying their results. Some of these tools are effective for presenting any data, not just query results.


Using HTML tables to display query results

You can use HTML tables to specify how the results of a query appear on a page. To do so, you put the cfoutput tag inside the table tags. You can also use the HTML th tag to put column labels in a header row. To create a row in the table for each row in the query results, put the tr block inside the cfoutput tag.

In addition, you can use CFML functions to format individual pieces of data, such as dates and numeric values.

To put the query results in a table:

  1. Open the ColdFusion page actionpage.cfm in your editor.
  2. Modify the page so that it appears as follows:
    3. <html>
<head>
<title>Retrieving Employee Data Based on Criteia from Form</title>
</head>

<body>
<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary
   FROM Employee
   WHERE LastName=<cfqueryparam value="#Form.LastName#"
CFSQLType="CF_SQL_VARCHAR">
</cfquery>
<h4>Employee Data Based on Criteria from Form</h4>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Salary</th>
</tr>
<cfoutput query="GetEmployees">
<tr>
<td>#FirstName#</td>
<td>#LastName#</td>
<td>#Salary#</td>
</tr>
</cfoutput>
</table>
<br>
<cfif IsDefined("Form.Contractor")>
   <cfoutput>Contractor: #Form.Contractor#</cfoutput>
</cfif>
</body>
</html>
  3. Save the page as actionpage.cfm within the myapps directory.
  4. View formpage.cfm in your browser.
  5. Enter Smith in the Last Name text box and submit the form.
  6. The records that match the criteria specified in the form appear in a table.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<table>
Puts data into a table.
<tr>
   <th>First Name</th>
   <th>Last Name</th>
   <th>Salary</th>
</tr>
In the first row of the table, includes three columns, with the headings: First Name, Last Name, and Salary.
<cfoutput query="GetEmployees">
Gets ready to display the results of the GetEmployees query.
<tr>
   <td>#FirstName#</td>
   <td>#LastName#</td>
   <td>#Salary#</td>
</tr>
Creates a new row in the table, with three columns. For a record, puts the value of the FirstName field, the value of the LastName field, and the value of the Salary field.
</cfoutput>
Keeps getting records that matches the criteria, and displays each row in a new table row until you run out of records.
</table>
End of table.


Formatting individual data items

You can format individual data items. For example, you can format the Salary field as a monetary value. To format the Salary using the dollar format, you use the CFML expression DollarFormat(number).

To change the format of the Salary:

  1. Open the file actionpage.cfm in your editor.
  2. Change the line
    3. <td>#Salary#</td>

to

<td>#DollarFormat(Salary)#</td>
  3. Save the page.


Building flexible search interfaces

One option with forms is to build a search based on the form data. For example, you could use form data as part of the WHERE clause to construct a database query.

To give users the option to enter multiple search criteria in a form, you can wrap conditional logic around a SQL AND clause as part of the WHERE clause. The following action page allows users to search for employees by department, last name, or both.

Note: ColdFusion provides the Verity search utility that you can also use to perform a search. For more information, see Building a Search Interface.

To build a more flexible search interface:

  1. Open the ColdFusion page actionpage.cfm in your editor.
  2. Modify the page so that it appears as follows:
    3. <html>
<head>
<title>Retrieving Employee Data Based on Criteia from Form</title>
</head>
<body>
<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.FirstName,
      Employee.LastName,
      Employee.StartDate,
      Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID = Employee.Dept_ID
   <cfif IsDefined("Form.Department")>
AND Departmt.Dept_Name=<cfqueryparam value="#Form.Department#"
         CFSQLType="CF_SQL_VARCHAR">
   </cfif>
   <cfif Form.LastName IS NOT "">
      AND Employee.LastName=<cfqueryparam value="#Form.LastName#"
         CFSQLType="CF_SQL_VARCHAR">
   </cfif>
</cfquery>

<h4>Employee Data Based on Criteria from Form</h4>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Salary</th>
</tr>
<cfoutput query="GetEmployees">
<tr>
<td>#FirstName#</td>
<td>#LastName#</td>
<td>#Salary#</td>
</tr>
</cfoutput>
</table>
</body>
</html>
  3. Save the file.
  4. View formpage.cfm in your browser.
  5. Select a department, optionally enter a last name, and submit the form.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
SELECT  Departmt.Dept_Name,
   Employee.FirstName,
   Employee.LastName,
   Employee.StartDate,
   Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID =
      Employee.Dept_ID
Retrieves the fields listed from the Departmt and Employee tables, joining the tables based on the Dept_ID field in each table.
   <cfif IsDefined("FORM.Department")>
   AND Departmt.Dept_Name = <cfqueryparam
      value="#Form.Department#"
      CFSQLType="CF_SQL_VARCHAR">
   </cfif>
If the user specified a department on the form, only retrieves records where the department name is the same as the one the user specified. You must use pound signs in the SQL AND statement to identify Form.Department as a ColdFusion variable, but not in the IsDefined function.
<cfif Form.LastName IS NOT "">
AND Employee.LastName = <cfqueryparam
      value="#Form.LastName#"
      CFSQLType="CF_SQL_VARCHAR">
</cfif>
If the user specified a last name in the form, only retrieves the records in which the last name is the same as the one the user entered in the form.


Returning results to the user

When you return your results to the user, you must make sure that your pages respond to the user’s needs and are appropriate for the type and amount of information. In particular you must consider the following situations:

  • When there are no query results
  • When you return partial results


Handling no query results

Your code must accommodate the cases where a query does not return any records. To determine whether a search has retrieved records, use the RecordCount query variable. You can use the variable in a conditional logic expression that determines how to display search results appropriately to users.

For more information on query variables, including RecordCount, see Accessing and Retrieving Data.

For example, to inform the user when no records were found by the GetEmployees query, insert the following code before displaying the data:

<cfif GetEmployees.RecordCount IS "0">
   No records match your search criteria. <BR>
<cfelse>

You must do the following:

  • Prefix RecordCount with the query name.
  • Add a procedure after the cfif tag that displays a message to the user.
  • Add a procedure after the cfelse tag to format the returned data.
  • Follow the second procedure with a </cfif> tag end to indicate the end of the conditional code.

To return search results to users:

  1. Edit the page actionpage.cfm.
  2. Change the page so that it appears as follows:
    3. <html>
<head>
<title>Retrieving Employee Data Based on Criteia from Form</title>
</head>

<body>
<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.FirstName,
      Employee.LastName,
      Employee.StartDate,
      Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID = Employee.Dept_ID
   <cfif isdefined("Form.Department")>
      AND Departmt.Dept_Name = <cfqueryparam value="#Form.Department#"
         CFSQLType="CF_SQL_VARCHAR">
   </cfif>
   <cfif Form.LastName is not "">
      AND Employee.LastName = <cfqueryparam value="#Form.LastName#"
         CFSQLType="CF_SQL_VARCHAR">
   </cfif>
</cfquery>

<cfif GetEmployees.recordcount is "0">
No records match your search criteria. <br>
Please go back to the form and try again.
<cfelse>
<h4>Employee Data Based on Criteria from Form</h4>
<table>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Salary</th>
</tr>
<cfoutput query="GetEmployees">
<tr>
<td>#FirstName#</td>
<td>#LastName#</td>
<td>#Salary#</td>
</tr>
</cfoutput>
</cfif>
</table>
</body>
</html>
  3. Save the file.
  4. Return to the form, enter search criteria, and submit the form.
  5. If no records match the criteria you specified, the message appears.


Returning results incrementally

You can use the cfflush tag to incrementally output long-running requests to the browser before a ColdFusion page is fully processed. This allows you to give the user quick feedback when it takes a long time to complete processing a request. For example, when a request takes time to return results, you can use cfflush to display the message, “Processing your request -- please wait.”. You can also use it to incrementally display a long list as it gets retrieved.

The first time you use the cfflush tag on a page, it sends to the browser all of the HTML headers and any other available HTML. Subsequent cfflush tags on the page send only the output that ColdFusion generates since the previous flush.

You can specify an interval attribute to tell ColdFusion to flush the output each time that at least the specified number of bytes become available. (The count does not include HTML headers and any data that is already available when you make this call.) You can use the cfflush tag in a cfloop to incrementally flush data as it becomes available. This format is particularly useful when a query responds slowly with large amounts of data.

When you flush data, make sure that a sufficient amount of information is available, because some browsers might not respond if you flush only a very small amount. Similarly, if you use an interval attribute, set it for a reasonable size, such as a few hundred bytes or more but not many thousands of bytes.

Caution:After you use the cfflush tag on a page, any CFML function or tag on the page that modifies the HTML header causes an error. These include the cfcontent, cfcookie, cfform, cfheader, cfhtmlhead, and cflocation tags. You also get an error if you use the cfset tag to set a Cookie scope variable. You can catch all errors, except Cookie errors, with a cfcatch type="template" tag. Catch cookie errors with cfcatch type="Any".

The following example uses the cfloop tag and the rand() random number generating function to artificially delay the generation of data for display. It simulates a situation in which it takes time to retrieve the first data and additional information becomes available slowly.

<html>
<head>
   <title>Your Magic numbers</title>
</head>

<body>
<h1>Your Magic numbers</h1>
<P>It will take us a little while to calculate your ten magic numbers.
It takes a lot of work to find numbers that truly fit your personality.
So relax for a minute or so while we do the hard work for you.</P>
<h2>We are sure you will agree it was worth the short wait!</h2>
<cfflush>

<cfflush interval=10>
<!--- Delay Loop to make is seem harder --->
<cfloop index="randomindex" from="1" to="200000" step="1">
   <cfset random=rand()>
</cfloop>

<!--- Now slowly output 10 random numbers --->
<cfloop index="Myindex" from="1" to="10" step="1">
   <cfloop index="randomindex" from="1" to="100000" step="1">
      <cfset random=rand()>
   </cfloop>
   <cfoutput>
      Magic number number #Myindex# is:&nbsp;&nbsp;#RandRange(
100000, 999999)#<br><br>
   </cfoutput>
</cfloop>
</body>
</html>


Reviewing the code

The following table describes the code and its function:

Code
Description
<h2>We are sure you will agree it was
   worth the short wait!</h2>
<cfflush>
Sends the HTML header and all HTML output to the cfflush tag to the user. This displays the explanatory paragraph and H2 tag contents.
<cfflush interval=10>
Flushes additional data to the user every time at least 10 bytes are available.
<cfloop index="randomindex" from="1"
      to="200000" step="1">
   <cfset random=Rand()>
</cfloop>
Inserts an artificial delay by using the Rand function to calculate many random numbers.
<cfloop index="Myindex" from="1"
      to="10" step="1">
   <cfloop index="randomindex"
      from="1" to="100000" step="1">
   <cfset random=rand()>
   </cfloop>
   <cfoutput>
   Magic number number #Myindex#
      is:&nbsp;&nbsp;#RandRange
      (100000,999999)#<br><br>
   </cfoutput>
</cfloop>
Generates and displays 10 random numbers. This code uses two loops. The outer loop repeats ten times, once for each number to display. The inner loop uses the rand function to create another delay by generating more (unused) random numbers. It then calls the RandRange function to generate a six-digit random number for display.


Dynamically populating list boxes

In Form controls, you hard-coded a form's list box options. Instead of manually entering the information on a form, you can dynamically populate a list box with database fields. When you code this way, the form page automatically reflects the changes that you make to the database.

You use two tags to dynamically populate a list box:

  • Use the cfquery tag to retrieve the column data from a database table.
  • Use the cfoutput tag with the query attribute within the select tag to dynamically populate the options of this form control.

To dynamically populate a list box:

  1. Open the file formpage.cfm in ColdFusion Studio.
  2. Modify the file so that it appears as follows:
    3. <html>
<head>
<title>Input form</title>
</head>
<body>
<cfquery name="GetDepartments" datasource="CompanyInfo">
SELECT DISTINCT Location
FROM Departmt
</cfquery>

<!--- Define the action page in the form tag.
   The form variables will pass to this page
   when the form is submitted --->

<form action="actionpage.cfm" method="post">

<!-- text box -->
<p>
First Name: <input type="Text" name="FirstName" size="20" maxlength="35"><br>
Last Name: <input type="Text" name="LastName" size="20" maxlength="35"><br>
Salary: <input type="Text" name="Salary" size="10" maxlength="10">
</p>

<!-- list box -->
City

<select name="City">
<cfoutput query="GetDepartments">
<option value="#GetDepartments.Location#">
#GetDepartments.Location#
</option>
</cfoutput>
</select>

<!-- radio buttons -->
<p>
Department:<br>
<input type="radio" name="Department" value="Training">Training<br>
<input type="radio" name="Department" value="Sales">Sales<br>
<input type="radio" name="Department" value="Marketing">Marketing<br>
<input type="radio" name="Department" value="HR">HR<br>
</p>

<!-- check box -->
<p>
Contractor? <input type="checkbox" name="Contractor" value="Yes" checked>Yes
</p>

<!-- reset button -->
<input type="reset" name="ResetForm" value="Clear Form">

<!-- submit button -->
<input type="submit" name="SubmitForm" value="Submit">
</form>
</body>
</html>
  3. Save the page as formpage.cfm.
  4. View formpage.cfm in a browser.

    5. The changes that you just made appear in the form.

    Remember that you need an action page to submit values.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cfquery name="GetDepartments"
datasource="CompanyInfo">
SELECT DISTINCT Location
FROM Departmt
</cfquery>
Get the locations of all departments in the Departmt table. The DISTINCT clause eliminates duplicate location names from the returned query results.
<select name="City">
<cfoutput query="GetDepartments">
<option
value="#GetDepartments.Location#">
#GetDepartments.Location#
</option>
</cfoutput>
</select>
Populate the City selection list from the Location column of the GetDepartments query. The control has one option for each row returned by the query.


Creating dynamic check boxes and multiple-selection list boxes

When an HTML form contains either a list of check boxes with the same name or a multiple-selection list box (that is, where users can select multiple items from the list), the user's entries are made available as a comma-delimited list with the selected values. These lists can be very useful for a wide range of inputs.

Note: If the user does not select a check box or make a selection from a list box, no variable is created. The cfinsert and cfupdate tags do not work correctly if there are no values. To correct this problem, make the form fields required, use Dynamic SQL, or use cfparam to establish a default value for the form field.


Check boxes

When you put a series of check boxes with the same name in an HTML form, the variable that is created contains a comma-delimited list of values. The values can be either numeric values or alphanumeric strings. These two types of values are treated slightly differently.


Handling numeric values

Suppose you want a user to select one or more departments using check boxes. You then query the database to retrieve detailed information on the selected department(s). The code for a simple set of check boxes that lets the user select departments looks like this:

<input type="checkbox"
   name="SelectedDepts"
   value="1">
   Training<br>

<input type="checkbox"
   name="SelectedDepts"
   value="2">
   Marketing<br>

<input type="checkbox"
   name="SelectedDepts"
   value="3">
   HR<br>

<input type="checkbox"
   name="SelectedDepts"
   value="4">
   Sales<br>
</html>

The user sees the name of the department, but the value attribute of each check box is a number that corresponds to the underlying database primary key for the department's record.

If the user checks the Marketing and Sales items, the value of the SelectedDept form field is "2,4" and you use the SelectedDepts in the following SQL statement:

SELECT *
   FROM Departmt
   WHERE Dept_ID IN ( #Form.SelectedDepts# )

The ColdFusion Server sends the following statement to the database:

SELECT *
   FROM Departmt
   WHERE Dept_ID IN ( 2,4 )


Handling string values

To search for a database field containing string values (instead of numeric), you must modify the checkbox and cfquery syntax.

The first example searched for department information based on a numeric primary key field called Dept_ID. Suppose, instead, that the primary key is a database field called Dept_Name that contains string values. In that case, your code for check boxes should look like this:

<input type="checkbox"
   name="SelectedDepts"
   value="Training">
   Training<br>

<input type="checkbox"
   name="SelectedDepts"
   value="Marketing">
   Marketing<br>

<input type="checkbox"
   name="SelectedDepts"
   value="HR">
   HR<br>

<input type="checkbox"
   name="SelectedDepts"
   value="Sales">
   Sales<br>

If the user checked Marketing and Sales, the value of the SelectedDepts form field would be the list Marketing,Sales and you use the following SQL statement:

SELECT *
   FROM Departmt
   WHERE Dept_Name IN
   (#ListQualify(Form.SelectedDepts,"'")#)

Note: In SQL, all strings must be surrounded in single quotes. The ListQualify function returns a list with the specified qualifying character (here, a single quote) around each item in the list.

If you select the second and fourth check boxes in the form, the following statement gets sent to the database:

SELECT *
   FROM Departmt
   WHERE Dept_Name IN ('Marketing','Sales')


Multiple selection lists

ColdFusion treats the result when a user selects multiple choices from a list box (HTML input type select with attribute multiple) just like results of selecting multiple check boxes. The data made available to your page from any multiple selection list box is a comma-delimited list of the entries selected by the user; for example, a list box could contain the four entries: Training, Marketing, HR, and Sales. If the user selects Marketing and Sales, the form field variable value is Marketing,Sales.

You use multiple selection lists to search a database in the same way that you use check boxes.


Handling numeric values

Suppose you want the user to select departments from a multiple-selection list box. The query retrieves detailed information on the selected department(s):

Select one or more companies to get more information on:
<select name="SelectDepts" multiple>
   <option value="1">Training
   <option value="2">Marketing
   <option value="3">HR
   <option value="4">Sales
</select>

If the user selects the Marketing and Sales items, the value of the SelectDepts form field is 2,4. If this parameter is used in the following SQL statement:

SELECT *
   FROM Departmt
   WHERE Dept_ID IN (#form.SelectDepts#)

the following statement is sent to the database:

SELECT *
   FROM Departmt
   WHERE Dept_ID IN (2,4)


Handling string values

Suppose you want the user to select departments from a multiple selection list box. The database search field is a string field. The query retrieves detailed information on the selected department(s):

<select name="SelectDepts" multiple>
   <option value="Training">Training
   <option value="Marketing">Marketing
   <option value="HR">HR
   <option value="Sales">Sales
</select>

If the user selects the Marketing and Sales items, the SelectDepts form field value is Marketing,Sales.

Just as you did when using check boxes to search database fields containing string values, use the ColdFusion ListQualifyfunction with multiple-selection list boxes:

SELECT *
   FROM Departmt
   WHERE Dept_Name IN (#ListQualify(Form.SelectDepts,"'")#)

The following statement gets sent to the database:

SELECT *
   FROM Departmt
   WHERE Dept_Name IN ('Marketing','Sales')


Validating form field data types

One limitation of standard HTML forms is that you cannot validate that users input the type or range of data you expect. ColdFusion enables you to do several types of data validation by adding hidden fields to forms.

The following table describes the hidden field suffixes that you can use to do validation:

Field Suffix
Value Attribute
Description
_integer
Custom error message
Verifies that the user entered a number. If the user enters a floating point value, it is rounded to an integer.
_float
Custom error message
Verifies that the user entered a number. Does not do any rounding of floating point values.
_range
MIN=MinValue
MAX=MaxValue
Verifies that the numeric value entered is within the specified boundaries. You can specify one or both of the boundaries separated by a space.
_date
Custom error message
Verifies that the user entered a date and converts the date into the proper ODBC date format. Will accept most common date forms; for example,
9/1/98; Sept. 9, 1998.
_time
Custom error message
Verifies that the user correctly entered a time and converts the time to the proper ODBC time format.
_eurodate
Custom error message
Verifies that the user entered a date in a standard European date format and converts into the proper ODBC date format.

Note: Adding a validation rule to a field does not make it a required field. You need to add a separate _required hidden field if you want to ensure user entry.

The following procedure creates a simple form for entering a start date and a salary. It uses hidden fields to ensure that you enter data and that the data is in the right format.

This example illustrates another concept that might seem surprising. You can use the same CFML page as both a form page and its action page. Because the only action is to display the values of the two variables that you enter, the action is on the same page as the form.

Using a single page for both the form and action provides the opportunity to illustrate the use of the IsDefined function to check that data exists. This way, the form does not show any results until you submit the input.

To validate the data that users enter in the insert form:

  1. Create a new page with the following text:
    2. <html>
<head>
   <title>Simple Data Form</title>
</head>
<body>
<h2>Simple Data Form</h2>

<!--- Form part --->
<form action="datatest.cfm" method="Post">
   <input type="hidden"
      name="StartDate_required"
      value="You must enter a start date.">
   <input type="hidden"
      name="StartDate_date"
      value="Enter a valid date as the start date.">
   <input type="hidden"
      name="Salary_required"
      value="You must enter a salary.">
   <input type="hidden"
      name="Salary_float"
      value="The salary must be a number.">
   Start Date:
   <input type="text"
      name="StartDate" size="16"
      maxlength="16"><br>
   Salary:
   <input type="text"
      name="Salary"
      size="10"
      maxlength="10"><br>
   <input type="reset"
      name="ResetForm"
      value="Clear Form">
   <input type="submit"
      name="SubmitForm"
      value="Insert Data">
</form>
<br>

<!--- Action part --->
<cfif isdefined("Form.StartDate")>
   <cfoutput>
      Start Date is: #DateFormat(Form.StartDate)#<br>
      Salary is: #DollarFormat(Form.Salary)#
   </cfoutput>
</cfif>
</html>
  2. Save the file as datatest.cfm.
  3. View the file in your browser, omit a field or enter invalid data, and click the Submit button.

When the user submits the form, ColdFusion scans the form fields to find any validation rules you specified. The rules are then used to analyze the user's input. If any of the input rules are violated, ColdFusion sends an error message to the user that explains the problem. The user then must go back to the form, correct the problem, and resubmit the form. ColdFusion does not accept form submission until the user enters the entire form correctly.

Because numeric values often contain commas and dollar signs, these characters are automatically deleted from fields with _integer, _float, or _range rules before the form field is validated and the data is passed to the form's action page.


Reviewing the code

The following table describes the code and its function:

Code
Description
<form action="actionpage.cfm"
   method="post">
Gather the information from this form using the Post method, and do something with it on the page dataform.cfm, which is this page.
<input type="hidden"
   name="StartDate_required"
   value="You must enter a start date.">
<input type="hidden"
   name="StartDate_date"
   value="Enter a valid date as the
   start date.">
Require input into the StartDate input field. If there is no input, display the error information “You must enter a start date.” Require the input to be in a valid date format. If the input is not valid, display the error information “Enter a valid date as the start date.”
<input type="hidden"
   name="Salary_required"
   value="You must enter a salary.">
<input type="hidden"
   name="Salary_float"
   value="The salary must be a number.">
Require input into the Salary input field. If there is no input, display the error information “You must enter a salary.” Require the input to be in a valid number. If it is not valid, display the error information “The salary must be a number.”
Start Date:
<input type="text"
   name="StartDate" size="16"
   maxlength="16"><br>
Create a text box called StartDate in which users can enter their starting date. Make it exactly 16 characters wide.
Salary:
<input type="text"
   name="Salary"
   size="10"
   maxlength="10"><br>
Create a text box called Salary in which users can enter their salary. Make it exactly ten characters wide.
<cfif isdefined("Form.StartDate")>
   <cfoutput>
      Start Date is:
         #DateFormat(Form.StartDate)#<br>
      Salary is:
         #DollarFormat(Form.Salary)#
   </cfoutput>
</cfif>
Output the values of the StartDate and Salary form fields only if they are defined. They are not defined until you submit the form, so they do not appear on the initial form. Use the DateFormat function to display the start date in the default date format. Use the DollarFormat function to display the salary with a dollar sign and commas.

  Previous


Building Dynamic Forms

This chapter describes how to use the cfform tag to enrich your HTML forms with sophisticated graphical controls, including several Java applet-based controls. You can use these controls without writing a line of Java code.

Contents
  • Creating forms with the cfform tag
  • Building tree controls with cftree
  • Building drop-down list boxes
  • Building text input boxes
  • Building slider bar controls
  • Creating data grids with cfgrid
  • Embedding Java applets
  • Input validation with cfform controls
  • Input validation with JavaScript
Next


Creating forms with the cfform tag

You already learned how to use HTML forms to gather user input (see Retrieving and Formatting Data). This chapter shows you how to use the cfform tag to create dynamic forms in CFML. In addition to standard HTML form controls, the cfform tag allows you to create forms that contain the following controls:

  • Text boxes in which you can specify the appearance, such as fonts and colors
  • Text inputs that allow you to validate the data entered into the control
  • Predefined ColdFusion Java applet based controls, including trees, sliders, and grids
  • Custom Java applets that act as form elements

Most cfform controls offer input validation attributes that you can use to validate user entry, selection, or interaction. This means you do not have to write separate CFML code specifically for input validation, as you do in HTML forms.


Using HTML and cfform

ColdFusion dynamically generates HTML forms from cfform tags and passes to the browser any HTML code that it finds in the form. As a result, you can also do the following:

  • You can use the passthrough attribute of the cfform, cfinput, and cfselect tags to enter any HTML attributes that are not explicitly allowed in these tags. The attribute values are passed through to the HTML generated by these form tags.
  • You can replace your existing HTML form tags with cfform and your forms will work fine.
  • ColdFusion passes to the action page of the cfform the variable Form.fieldnames which contains the names of the form fields submitted from the form.


The cfform controls

The following table describes the ColdFusion controls that you use in forms created using cfform. You can use these tags only inside a cfform tag.

Control
Description
For more information
cfgrid
Java applet-based control that creates a data grid that you can populate from a query or by defining the contents of individual cells. You can also use grids to insert, update, and delete records from a data source.
Creating data grids with cfgrid.
cfslider
Java applet-based control that defines a slider.
Building slider bar controls.
cfinput
Places radio buttons, check boxes, text input boxes, and password entry boxes. Equivalent to the HTML input tag with the addition of input validation.
Input validation with cfform controls.
cftree
Java applet-based controls that define a tree control and individual tree control items.
Building tree controls with cftree.
cftextinput
Java applet-based control that defines a text input box.
Building text input boxes.
cfselect
Drop-down list box not a Java applet). Equivalent to the HTML select tag with the addition of input validation and data binding.
Building drop-down list boxes.
cfapplet
Embed your own Java applets in the form.
Embedding Java applets.


Preserving input data with preservedata

The cfform attribute preservedata tells ColdFusion to continue displaying the data that a user entered in the form after the user submits the form. Data is preserved in the cfinput, cfslider, cftextinput, and cftree controls and in cfselect controls populated by queries. If you specify a default value for a control, and a user overrides that default in the form, the user input is preserved.

You can retain data on the form in the following circumstance:

  • The form’s action posts to the same ColdFusion page as the form itself, and the control names are the same.

For example, if you save this form as preserve.cfm, it continues to display any text that you enter after you submit it:

<cfform action="preserve.cfm" preservedata="Yes">
   <p>Please enter your name:
   <cfinput type="Text" name="UserName" required="Yes"><p>
   <input type="Submit" name=""> <input type="RESET">
</cfform>


Usage notes for the preservedata attribute

When using the preservedata attribute, follow these guidelines:

  • In cftree, the preservedata attribute causes the tree to expand the tree to the previously selected element. For this to work correctly, you must also set the completePath attribute to True.
  • The preservedata attribute has no effect on cfgrid. If you populate the control from a query, you must update the data source with the new data (typically by using cfgridupdate) before redisplaying the grid. The grid then displays the updated database information.


Browser considerations

The applet-based controls for cfform--cfgrid, cfslider, cftextinput, and cftree--use JavaScript and Java to display their content. To allow them to display consistently across a variety of browsers, these applets use the Java plug-in. As a result, they are independent of the level of Java support provided by the browser.

ColdFusion downloads and installs the browser plug-in if necessary. Some browsers display a single permission dialog box asking you to confirm the plug-in install. Other browsers, particularly older versions of Netscape, require you to navigate some simple option screens.

Because the controls use JavaScript to return data to ColdFusion, if you disable JavaScript in your browser, it cannot properly run forms that contain these controls. In that case, the controls still display, but data return and validation does not work and you can receive a JavaScript error.

Because Java is handled by the plug-in and not directly by the browser, disabling Java execution in the browser does not affect the operation of the controls. If for some other reason, however, the browser is unable to render the controls as requested, a "notsupported" message appears in place of the control.

You can use the cfform tag’s notsupported attribute to specify an alternate error message.


Building tree controls with cftree

The cftree tag lets you display hierarchical information within a form in a space-saving collapsible tree populated from data source queries. To build a tree control with cftree, you use individual cftreeitem tags to populate the control. You can specify one of six built-in icons to represent individual items in the tree control, or supply a file path or URL to your GIF image.

Note: The cftree tag requires the client to download a Java applet. Downloading an applet takes time; therefore, using cftree can be slightly slower than using an HTML form element to retrieve the same information. In addition, browsers must be Java-enabled for cftree to work properly.

To create and populate a tree control from a query:

  1. Create a ColdFusion page with the following content:
    2. <cfquery name="engquery" datasource="CompanyInfo">
   SELECT FirstName + ' ' + LastName AS FullName
   FROM Employee
</cfquery>
<cfform name="form1" action="submit.cfm">
<cftree name="tree1"
   required="Yes"
   hscroll="No">
   <cftreeitem value="FullName"
      query="engquery"
      queryasroot="Yes"
      img="folder,document">
</cftree>
</cfform>
  2. Save the page as tree1.cfm and view it in your browser.

    3. The following figure shows the output of this code:

    This is a picture of the feature being described.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cftree name="tree1"
Creates a tree and name it tree1.
required="Yes"
Specifies that a user must select an item in the tree.
hscroll="No"
Does not allow horizontal scrolling.
<cftreeitem value="FullName"
query="engquery"
Creates an item in the tree and put the results of the query named engquery in it. Because this tag uses a query, it puts one item on the tree per query entry.
queryasroot="Yes"
Specifies the query name as the root level of the tree control.
img="folder,document"
Uses the images "folder" and "document" that ship with ColdFusion in the tree structure.
When populating a cftree with data from a cfquery, you can specify images or filenames for each level of the tree as a comma-separated list.


Grouping output from a query

In a query that you display using a cftree control, you might want to organize your employees by the department. In this case, you separate column names with commas in the cftreeitem value attribute.

To organize the tree based on ordered results of a query:

  1. Create a ColdFusion page named tree2.cfm with the following content:
    2. <!--- CFQUERY with an ORDER BY clause --->
<cfquery name="deptquery" datasource="CompanyInfo">
   SELECT Dept_ID, FirstName + ' ' + LastName
   AS FullName
   FROM Employee
   ORDER BY Dept_ID
</cfquery>

<!--- Build the tree control --->
<cfform name="form1" action="submit.cfm">

<cftree name="tree1"
   hscroll="No"
   border="Yes"
   height="350"
   required="Yes">

<cftreeitem value="Dept_ID, FullName"
   query="deptquery"
   queryasroot="Dept_ID"
   img="cd,folder">

</cftree>
<br>
<br><input type="Submit" value="Submit">
</cfform>
  2. Save the page and view it in your browser.

    3. This is a picture of the feature being described.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
ORDER BY Dept_ID
Order the query results by department.
<cftreeitem value="Dept_ID,FullName"
Populate the tree with the Department ID, and under each department, the Full Name for each employee in the department.
queryasroot="Dept_ID"
Label the root "Dept_ID".
img="cd,folder">
Use the ColdFusion-supplied CD image for the root level and Folder image for the department IDs. The names are preceded by a bullet.

The cftreeitem comma-separated img and the value attributes both correspond to the tree level structure. If you leave out the img attribute, ColdFusion uses the folder image for all levels in the tree except the individual items, which have bullets.


The cftree form variables

The cftree tag lets you force a user to select an item from the tree control by setting the required attribute to Yes. With or without the required attribute, ColdFusion passes two form variables to the application page specified in the cfform action attribute:

  • Form.treename.path Returns the complete path of the user selection, in the form: [root]\node1\node2\node_n\value
  • Form.treename.node Returns the node of the user selection.

To return the root part of the path, set the completepath attribute of cftree to Yes; otherwise, the path value starts with the first node. If you specify a root name for a tree item using queryasroot, that value is returned as the root. If you do not specify a root name, ColdFusion returns the query name as the root. If there is no query name, ColdFusion returns the tree name as the root.

In the previous example, if the user selects the name "John Allen" in the tree, ColdFusion returns the following form variables:

Form.tree1.path = Dept_ID\3\John Allen
Form.tree1.node = John Allen

You can specify the character used to delimit each element of the path form variable in the cftree delimiter attribute. The default is a backslash.


Input validation

Although the cftree does not include a validate attribute, you can use the required attribute to force a user to select an item from the tree control. In addition, you can use the onvalidate attribute to specify your own JavaScript code to perform validation.


Structuring tree controls

Tree controls built with cftree can be very complex. Knowing how to specify the relationship between multiple cftreeitem entries helps you handle the most complex of cftree constructs.


Creating a one-level tree control

This example consists of a single root and a number of individual items:

<cfquery name="deptquery" datasource="CompanyInfo">
   SELECT Dept_ID, FirstName + ' ' + LastName
   AS FullName
   FROM Employee
   ORDER BY Dept_ID
</cfquery>

<cfform name="form1" action="submit.cfm">
   <cftree name="tree1">
      <cftreeitem value="FullName"
      query="deptquery"
      queryasroot="Department">
   </cftree>
<br>
<input type="submit" value="Submit">
</cfform>


Creating a multilevel tree control

The following figure shows an example of a multilevel tree:

This is a picture of the feature being described.

When populating a cftree, you create the multilevel structure of the tree by specifying a parent for each cftreeitem in the tree. The parent attribute of cftreeitem allows your cftree to show relationships between elements in the tree.

In this example, every cftreeitem, except the top level Divisions, specifies a parent. For example, the cftreeitem Development specifies a parent of Divisions.

The following code populates the tree directly, not from a query.

<cfform name="form2" action="cfform_submit.cfm">
<cftree name="tree1" hscroll="No" vscroll="No"
   border="No">
   <cftreeitem value="Divisions">
   <cftreeitem value="Development"
      parent="Divisions" img="folder">
   <cftreeitem value="Product One"
      parent="Development">
   <cftreeitem value="Product Two"
      parent="Development">
   <cftreeitem value="GUI"
      parent="Product Two" img="document">
   <cftreeitem value="Kernel"
      parent="Product Two" img="document">
   <cftreeitem value="Product Three"
      parent="Development">
   <cftreeitem value="QA"
      parent="Divisions" img="folder">
   <cftreeitem value="Product One"
      parent="QA">
   <cftreeitem value="Product Two" parent="QA">
   <cftreeitem value="Product Three"
      parent="QA">
   <cftreeitem value="Support"
      parent="Divisions" img="fixed">
   <cftreeitem value="Product Two"
      parent="Support">
   <cftreeitem value="Sales"
      parent="Divisions" img="cd">
   <cftreeitem value="Marketing"
      parent="Divisions" img="document">
   <cftreeitem value="Finance"
      parent="Divisions" img="element">
</cftree>

</cfform>


Image names in a cftree

The default image displayed in a tree is a folder. However, you can use the img attribute of cftreeitem to specify a different image.

When you use the img attribute, ColdFusion displays the specified image beside the tree items. You can specify a built-in ColdFusion image name, the file path to an image file, or the URL of an image of your choice, such as http://localhost/Myapp/Images/Level3.gif. As a general rule, make the height of your custom images less than 20 pixels.

When populating a cftree with data from a cfquery, you can use the img attribute of cftreeitem to specify images or filenames for each level of the tree as a comma-separated list.

The ColdFusion built-in image names are:

  • cd
  • computer
  • document
  • element
  • folder
  • floppy
  • fixed
  • remote

Note: You can also control the tree appearance by using the lookAndFeel attribute to specify a Windows, Motif, or Metal look.


Embedding URLs in a cftree

The href attribute in the cftreeitem tag lets you designate tree items as links. To use this feature in a cftree, you define the destination of the link in the href attribute of cftreeitem. The URL for the link can be a relative URL or an absolute URL as in the following examples.

To embed links in a cftree:

  1. Create a ColdFusion page named tree3.cfm with the following contents:
    2. <cfform action="submit.cfm">

<cftree name="oak"
   highlighthref="Yes"
   height="100"
   width="200"
   hspace="100"
   vspace="6"
   hscroll="No"
   vscroll="No"
   border="No">

   <cftreeitem value="Important Links">
   <cftreeitem value="Macromedia Home"
      parent="Important Links"
      img="document"
      href="http://www.macromedia.com">
   <cftreeitem value="ColdFusion Home"
      parent="Important Links"
      img="document"
      href="http://www.coldfusion.com">
</cftree>
</cfform>
  2. Save the page and view it in your browser. The following figure shows the output of this code:

    3. This is a picture of the feature being described.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
href="http://
www.macromedia.com">
Makes the node of the tree a link.
href="http://
www.coldfusion.com">
Makes the node of the tree a link.
Although this example does not show it, href can refer to the name of a column in a query if that query populates the tree item.


Specifying the tree item in the URL

When a user clicks on a tree item to link to a URL, the cftreeItemKey variable, which identifies the selected value, is appended to the URL in the form:

http://myserver.com?cftreeitemkey =selected_value

Automatically passing the name of the selected tree item as part of the URL makes it easy to implement a basic "drill down" application that displays additional information based on the selection. For example, if the specified URL is another ColdFusion page, it can access the selected value as the variable URL.cftreeitemkey.

To disable this behavior, set the appendkey attribute in the cftree tag to No.


Building drop-down list boxes

The drop-down list box that you can create in a cfform tag with cfselect is similar to the HTML select tag. However, cfselect gives you more control over user inputs, provides error handling, and, most importantly, allows you to automatically populate the selection list from a query.

You can populate the drop-down list box from a query, or using lists of option elements created by the option tag. The syntax for the option tag with cfselect is the same as for the HTML option tag.

When you populate a cfselect with data from a query, you only need to specify the name of the query that is supplying data for the cfselect and the query column name for each list element to display.

To populate a drop-down list box with query data using cfselect:

  1. Create a ColdFusion page with the following content:
    2. <cfquery name="getNames"
   datasource="CompanyInfo">
   SELECT * FROM Employee
</cfquery>

<cfform name="Form1" action="submit.cfm">

   <cfselect name="employees"
      query="getNames"
      value="Emp_ID"
      display="FirstName"
      required="Yes"
      multiple="Yes"
      size="8">
   </cfselect>

   <br><input type="Submit" value="Submit">
</cfform>
  2. Save the file as selectbox.cfm and view it in your browser. The following figure shows the output of this code:

    3. This is a picture of the feature being described.

Because the tag includes the multiple attribute, the user can select multiple entries in the list box. Also, because the value tag specifies Emp_ID, the primary key for the Employee table, Employee IDs (not first names) get passed in the Form.Employee variable to the application page specified in the cfform action attribute.


Building text input boxes

The cftextinput tag in a cfform tag is similar to the HTML input type=text tag or the CFML cfinput type=text tag. With cftextinput, however, you can also specify font and alignment options, use the validate attribute to enable input validation using ColdFusion validation methods or your own JavaScript validation function, and use the required attribute to force the user to enter or change text.

The following example shows a basic cftextinput control. This example validates a date entry, which means that a user must enter a valid date in the form mm/dd/yy (the year can be up to four digits). For a complete list of validation formats, see the CFML Reference.

  1. Create a ColdFusion page with the following content:
    2. Please enter a date:<br>
<cfform name="Form1"
   action="submit.cfm">

   <cftextinput name="entertext"
      value="mm/dd/yy"
      maxlength="10"
      validate="date"
      width=100
      font="Trebuchet MS">
   <br>
   <br>
   <input type="Submit"
         value="Submit">

</cfform>
  2. Save the file as textentry.cfm and view it in your browser. The following figure shows the output of this code:

    3. This is a picture of the feature being described.

To get the value of the input text in the action page, use the variable Form.textinput_name; in this case, Form.entertext.


Building slider bar controls

You can use the cfslider control in a cfform tag to create a slider control and define a wide range of formatting options for slider label text, label font name, size, boldface, italics, and color, as well as slider scale increments, range, positioning, tick marks, and behavior. Slider bars are useful because they are highly visual and users cannot enter invalid values.

To create a slider control:

  1. Create a ColdFusion page with the following content:
    2. <cfform name="Form1" action="submit.cfm">

   <cfslider name="myslider"
      bgcolor="cyan"
      bold="Yes"
      range="0,1000"
      scale="100"
      value="600"
      fontsize="14"
      label="Slider %value%"
      height="60"
      tickmarkmajor="True"
      width="400">

</cfform>
  2. Save the file as slider.cfm and view it in your browser. The following figure shows the output of this code:

    3. This is a picture of the feature being described.

To get the value of the slider in the action page, use the variable Form.slider_name; in this case, Form.myslider.


Creating data grids with cfgrid

The cfgrid tag creates a cfform grid control that resembles a spreadsheet table and can contain data populated from a cfquery or from other sources of data. As with other cfform tags, cfgrid offers a wide range of data formatting options as well as the option of validating user selections with a JavaScript validation script.

You can also do the following tasks with cfgrid:

  • Sort data in the grid alphanumerically
  • Update, insert, and delete data
  • Display images in the grid

Users can sort the grid entries in ascending order by double-clicking any column header. Double-clicking again sorts the grid in descending order. You can also add sort buttons to the grid control.

When users select grid data and submit the form, ColdFusion passes the selection information as form variables to the application page specified in the cfform action attribute.

Just as the cftree tag uses cftreeitem, cfgrid uses the cfgridcolumn and cfgridrow tags. You can define a wide range of row and column formatting options, as well as a column name, data type, selection options, and so on. You use the cfgridcolumn tag to define individual columns in the grid or associate a query column with a grid column.

Use the cfgridrow tag to define a grid that does not use a query as the source for row data. If a query attribute is specified in cfgrid, the cfgridrow tags are ignored.

The cfgrid tag provides many attributes that control grid behavior and appearance. This chapter describes only the most important of these attributes. For detailed information on these attributes, see the CFML Reference.


Working with a data grid and entering data

The following figure shows an example grid created using the cfgrid tag:

This is a picture of the feature being described.

Navigating is fairly straightforward, but here are a few tips:

Action | Procedure
Sorting grid rows | Double-click the column header to sort a column in ascending order. Double-click again to sort the rows in descending order.
Rearranging columns | Click any column heading and drag the column to a new position.
Determining editable grid areas | When you click an editable cell, it is surrounded by a yellow box.
Determining noneditable grid areas | When you click a cell (or row or column) that you cannot edit, its background color changes. The default color is salmon pink.
Editing a grid cell | Double-click the cell. You must press Return when you finish entering the data.
Deleting a row | Click any cell in the row and click the Delete button.
Inserting a row | Click the Insert button. An empty row appears at the bottom of the grid. To enter a value in each cell, double-click the cell, enter the value, and click Return.

To populate a grid from a query:

  1. Create a new ColdFusion page named grid1.cfm with the following contents:
    2. <cfquery name="empdata" datasource="CompanyInfo">
   SELECT * FROM Employee
</cfquery>

<cfform name="Form1" action="submit.cfm" >

   <cfgrid name="employee_grid" query="empdata"
         selectmode="single">
      <cfgridcolumn name="Emp_ID">
      <cfgridcolumn name="LastName">
      <cfgridcolumn name="Dept_ID">
   </cfgrid>

<br><input type="Submit" value="Submit">
</cfform>

    Note: Use the cfgridcolumn display="No" attribute to hide columns that you want to include in the grid but not expose to an end user. You typically use this attribute to include columns such as the table’s primary key column in the results returned by cfgrid.
  2. Save the file and view it in your browser. The following figure shows the output of this code:

    3. This is a picture of the feature being described.


Reviewing the code

The following table describes the highlight code and its function:

Code
Description
<cfgrid name="employee_grid"
   query="empdata"
Create a grid named "employee_grid" and populate it with the results of the query "empdata".
If you specify a cfgrid tag with a query attribute defined and no corresponding cfgridcolumn attributes, the grid contains all the columns in the query.
selectmode="single">
Allow the user to select only one cell. Other modes are row, column, and edit.
<cfgridcolumn name="Emp_ID">
Put the contents of the Emp_ID column in the query results in the first column of the grid.
<cfgridcolumn name="LastName">
Put the contents of the LastName column in the query results in the second column of the grid.
<cfgridcolumn name="Dept_ID">
Put the contents of the Dept_ID column in the query results in the third column of the grid.


Creating an editable grid

You can build grids to allow users to edit data within them. Users can edit individual cell data, as well as insert, update, or delete rows. To enable grid editing, you specify selectmode="edit" in the cfgrid tag.

To let users add or delete grid rows, you also have to set the insert or delete attributes in cfgrid to Yes. Setting insert or delete to Yes causes the cfgrid tag to display insert and delete buttons as part of the grid, as the following figure shows:

This is a picture of the feature being described.

You can use a grid in two ways to make changes to your ColdFusion data sources:

  • Create a page to which you pass the cfgrid form variables. In that page perform cfquery operations to update data source records base on the form values returned by cfgrid.
  • Pass grid edits to a page that includes the cfgridupdate tag, which automatically extracts the form variable values and passes that data directly to the data source.

Using cfquery gives you complete control over interactions with your data source. The cfgridupdate tag provides a much simpler interface for operations that do not require the same level of control.


Controlling cell contents

The value, valuesDisplay, and valuesDelimiter attributes of the cfgridcolumn tag let you control the data that a user can enter into a cfgrid cell in the following ways:

  • By default, a cell is not editable. Use the cfgrid attribute selectmode="edit" to edit cell contents.
  • Use the type attribute to control sorting order, to make the fields check boxes, or to display an image.
  • Use the values attribute to specify a drop-down list of values from which the user can chose. You can use the valuesDisplay attribute to provide a list of items to display that differs from the actual values that you enter in the database. You can use the valuesDelimiter attribute to specify the separator between values in the values valuesDisplay lists.
  • While cfgrid does not have a validate attribute, it does have an onvalidate attribute that lets you specify a JavaScript function to perform validation.

For more information on controlling the cell contents, see the attribute descriptions in the CFML Reference.


How user edits are returned

ColdFusion creates the following arrays as Form variables to return edits to grid rows and cells:

Array reference
Description
gridname.colname[change_index]
Stores the new value of an edited cell.
gridname.Original.colname [change_index]
Stores the original value of the edited grid cell.
gridname.RowStatus.Action [change_index]
Stores the edit type made to the edited grid row: D for delete, I for insert, or U for update.

When a user selects and changes data in a row, ColdFusion creates arrays to store the following information for rows that are updated, inserted, or deleted:

  • The original values for all columns
  • The new column values
  • The type of change

For example, the following arrays are created if you update a cfgrid called "mygrid" consisting of two displayable columns, (col1, col2) and one hidden column (col3).

Form.mygrid.col1[ change_index ]
Form.mygrid.col2[ change_index ]
Form.mygrid.col3[ change_index ]
Form.mygrid.original.col1[ change_index ]
Form.mygrid.original.col2[ change_index ]
Form.mygrid.original.col3[ change_index ]
Form.mygrid.RowStatus.Action[ change_index ]

The value of change_index increments for each row that changes, and does not indicate the specific row number. When the user updates data or inserts or deletes rows, the action page gets one array for each changed column, and the RowStatus.Action array. The action page does not get arrays for unchanged columns.

If the user makes a change to a single cell in col2, you can access the edit operation, the original cell value, and the edited cell value in the following arrays:

Form.mygrid.RowStatus.Action[1]
Form.mygrid.col2[1]
Form.mygrid.original.col2[1]

If the user changes the values of the cells in col1 and col3 in one row and the cell in col2 in another row, the information about the original and changed values is in the following array entries:

Form.mygrid.RowStatus.Action[1]
Form.mygrid.col1[1]
Form.mygrid.original.col1[1]
Form.mygrid.col3[1]
Form.mygrid.original.col3[1]
Form.mygrid.RowStatus.Action[2]
Form.mygrid.col2[2]
Form.mygrid.original.col2[2]


Editing data in cfgrid

To enable grid editing, specify the selectmode="edit" attribute. When enabled, a user can edit cell data and insert or delete grid rows. When the user submits a cfform tag containing a cfgrid tag, data about changes to grid cells gets returned in the one-dimensional arrays described in the preceding section. You can reference these arrays as you would any other ColdFusion array.

Note: For code brevity, the following example handles only three of the fields in the Employee table. A more realistic example would include, at a minimum, all seven table fields. You might also consider hiding the contents of the Emp_ID column and automatically generating its value for new records, and displaying the Department name, from the Departmt table, in place of the Department ID.

To make the grid editable:

  1. Create a new ColdFusion page with the following contents:
    2. <cfquery name="empdata" datasource="CompanyInfo">
   SELECT * FROM Employee
</cfquery>

<cfform name="GridForm"
   action="handle_grid.cfm">

   <cfgrid name="employee_grid"
      height=425
      width=300
      vspace=10
      selectmode="edit"
      query="empdata"
      insert="Yes"
      delete="Yes">

      <cfgridcolumn name="Emp_ID"
         header="Emp ID"
         width=50
         headeralign="center"
         headerbold="Yes"
         select="No">

      <cfgridcolumn name="LastName"
         header="Last Name"
         width=100
         headeralign="center"
         headerbold="Yes">

      <cfgridcolumn name="Dept_ID"
         header="Dept"
         width=35
         headeralign="center"
         headerbold="Yes">

   </cfgrid>
   <br>
   <input type="Submit" value="Submit">
</cfform>
  2. Save the file as grid2.cfm and view it in your browser.

    3. The following figure shows the output of this code:

    This is a picture of the feature being described.

The following sections describe how to write handle_grid.cfm to process user edits to the grid.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfgrid name="employee_grid"
   height=425
   width=300
   vspace=10
   selectmode="edit"
   query="empdata"
   insert="Yes"
   delete="Yes">
Populates a cfgrid control with data from the empdata query. Selecting a grid cell enables you to edit it. You can insert and delete rows. The grid is 425 X 300 pixels and has 10 pixels of space above and below it.
<cfgridcolumn name="Emp_ID"
   header="Emp ID"
   width=50
   headeralign="center"
   headerbold="Yes"
   select="No">
Creates a 50-pixel wide column for the data in the Emp_ID column of the data source. Center a header named Emp ID and make it bold.
Does not allow users to select fields in this column for editing. Since this field is the table’s primary key, users should not be able to change it for existing records and the DBMS should generate this field as an automincrement value.
<cfgridcolumn name="LastName"
   header="Last Name"
   width=100
   headeralign="center"
   headerbold="Yes">
Creates a 100-pixel wide column for the data in the LastName column of the data source. Center a header named Last Name and make it bold.
<cfgridcolumn name="Dept_ID"
   header="Dept"
   width=35
   headeralign="center"
   headerbold="Yes">
Creates a 35-pixel wide column for the data in the Dept_ID column of the data source. Center a header named Dept and make it bold.


Updating the database with cfgridupdate

The cfgridupdate tag provides a simple mechanism for updating the database, including inserting and deleting records. It can add, update, and delete records simultaneously. It is particularly convenient because it automatically handles collecting the cfgrid changes from the various form variables and generates appropriate SQL statements to update your data source.

In most cases, use the cfgridupdate tag to update your database. However, this tag does not provide the complete SQL control that cfquery provides. In particular, the cfgridupdate tag lets you make the following changes:

  • Update only a single table.
  • Rows are deleted first, then rows are inserted, then any changes are made to existing rows. You cannot modify the order of changes.
  • Updating stops when an error occurs. It is possible that some database changes are made, but the tag does not provide any information on them.

To update the data source with cfgridupdate:

  1. Create a file ColdFusion page with the following contents:
    2. <html>
<head>
   <title>Update grid values</title>
</head>
<body>

<h3>Updating grid using cfgridupdate tag.</h3>

<cfgridupdate grid="employee_grid"
   datasource="CompanyInfo"
   tablename="Employee">

Click <a href="grid2.cfm">here</a> to display updated grid.

   </body>
</html>
  2. Save the file as handle_grid.cfm.
  3. View grid2.cfm in your browser, make changes to the grid, and then submit them.

Note: To update a grid cell, modify the cell contents, then press Return.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfgridupdate grid="employee_grid"
Update the database from the Employee_grid grid.
datasource="CompanyInfo"
Update the CompanyInfo data source.
tablename="Employee"
Update the Employee table.


Updating the database with cfquery

You can use the cfquery tag to update your database from the cfgrid changes. This provides you with full control over how the updates are made and lets you handle any errors that arise.

To update the data source with cfquery:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Catch submitted grid values</title>
</head>
<body>

<h3>Grid values for Form.employee_grid row updates</h3>

<cfif isdefined("Form.employee_grid.rowstatus.action")>

   <cfloop index = "Counter" from = "1" to =
      #arraylen(Form.employee_grid.rowstatus.action)#>

      <cfoutput>
         The row action for #Counter# is:
         #Form.employee_grid.rowstatus.action[Counter]#
         <br>
      </cfoutput>

      <cfif Form.employee_grid.rowstatus.action[counter] is "D">

         <cfquery name="DeleteExistingEmployee"
            datasource="CompanyInfo">
            DELETE FROM Employee
            WHERE Emp_ID=
               <cfqueryparam
                  value="#Form.employee_grid.original.Emp_ID[Counter]#"
                  CFSQLType="CF_SQL_INTEGER" >
         </cfquery>

      <cfelseif Form.employee_grid.rowstatus.action[counter] is "U">

         <cfquery name="UpdateExistingEmployee"
            datasource="CompanyInfo">
            UPDATE Employee
            SET
               LastName=
                  <cfqueryparam
                     value="#Form.employee_grid.LastName[Counter]#"
                     CFSQLType="CF_SQL_VARCHAR" >,
               Dept_ID=
                  <cfqueryparam
                     value="#Form.employee_grid.Dept_ID[Counter]#"
                     CFSQLType="CF_SQL_INTEGER" >
            WHERE Emp_ID=
            <cfqueryparam value="#Form.employee_grid.original.Emp_ID[Counter]#"
                  CFSQLType="CF_SQL_INTEGER">
         </cfquery>

      <cfelseif Form.employee_grid.rowstatus.action[counter] is "I">

         <cfquery name="InsertNewEmployee"
            datasource="CompanyInfo">
            INSERT into Employee (LastName, Dept_ID)
            VALUES
               (<cfqueryparam
                  value="#Form.employee_grid.LastName[Counter]#"
                  CFSQLType="CF_SQL_VARCHAR" >,
               <cfqueryparam value="#Form.employee_grid.Dept_ID[Counter]#"
                  CFSQLType="CF_SQL_INTEGER" >)
         </cfquery>

      </cfif>
   </cfloop>
</cfif>

Click <a href="grid2.cfm">here</a> to display updated grid.

</body>
</html>
  2. Rename your existing handle_grid.cfm file as handle_grid2.cfm to save it, then save this file as handle_grid.cfm.
  3. View grid2.cfm in your browser, make changes to the grid, and then submit them.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfif isdefined
  ("Form.employee_grid.rowstatus.action")>
  <cfloop index = "Counter" from = "1" to =
  #arraylen(Form.employee_grid.rowstatus.action)#>
If there is an array of edit types, then change the table. Otherwise, do nothing. Loops through the remaining code once for each row to be changed. Counter is the common index into the arrays of change information for the row being changed.
<cfoutput>
  The row action for #Counter# is:
  #Form.employee_grid.rowstatus.action[Counter]#
  <br>
</cfoutput>
Displays the action code for this row:
U, I, or D.
<cfif Form.employee_grid.rowstatus.action[counter] is "D">
  <cfquery name="DeleteExistingEmployee"
    datasource="CompanyInfo">
    DELETE FROM Employee
    WHERE Emp_ID=#Form.employee_grid.original.Emp_ID[Counter]#
  </cfquery>
If the action is to delete a row, generates a SQL DELETE query specifying the Emp_ID (the primary key) of the row to be deleted.
<cfelseif Form.employee_grid.rowstatus.action
    [counter] is "U">
  <cfquery name="UpdateExistingEmployee"
    datasource="CompanyInfo">
    UPDATE Employee
    SET LastName='#Form.employee_grid.LastName[Counter]#',
      Dept_ID=#Form.employee_grid.Dept_ID[Counter]#
  WHERE Emp_ID=#Form.employee_grid.original.Emp_ID[Counter]#
  </cfquery>
Otherwise, if the action is to update a row, generates a SQL UPDATE query to update the LastName and Dept_ID fields for the row specified by the Emp_ID primary table key.
<cfelseif Form.employee_grid.rowstatus.action[counter] is "I">

  <cfquery name="InsertNewEmployee"
  datasource="CompanyInfo">
  INSERT into Employee (LastName, Dept_ID)
  VALUES
    ('#Form.employee_grid.LastName[Counter]#',
     #Form.employee_grid.Dept_ID[Counter]#)
  </cfquery>
Otherwise, if the action is to insert a row, generates a SQL INSERT query to insert the employee’s last name and department ID from the grid row into the database. The INSERT assumes that the DBMS automatically increments the Emp_ID primary key. If you use the Dbase version of the CompanyInfo database that is provided for UNIX installations, the record is inserted without an Emp_ID number.
 </cfif>
 </cfloop>
</cfif>
Closes the cfif tag used to select among deleting, updating, and inserting.
Closes the loop used for each row to be changed.
Closes the cfif tag that surrounds all the active code.


Embedding Java applets

The cfapplet tag lets you embed Java applets either on a ColdFusion page or in a cfform. To use cfapplet, you must first register your Java applet using the ColdFusion Administrator Java Applets page (under Extensions on the Server tab). In the Administrator, you define the interface to the applet, encapsulating it so that each invocation of the cfapplet tag is very simple.

The cfapplet tag within a form offers several advantages over using the HTML applet tag:

  • Return values Since cfapplet requires a form field name attribute, you can avoid coding additional JavaScript to capture the applet’s return values. You can reference return values like any other ColdFusion form variable: Form.variablename.
  • Ease of use Since the applet’s interface is defined in the Administrator, each instance of the cfapplet tag in your pages only needs to reference the applet name and specify a form variable name.
  • Parameter defaults ColdFusion uses the parameter value pairs that you defined in the Administrator. You can override these values by specifying parameter value pairs in cfapplet.

When an applet is registered, you enter just the applet source and the form variable name:

<cfapplet appletsource="Calculator"
   name="calc_value">

By contrast, with the HTML applet tag, you must declare all the applet’s parameters every time you want to use it in a ColdFusion page.


Registering a Java applet

Before you can use a Java applet in your ColdFusion pages, you must register the applet in the Administrator.

To register a Java applet:

  1. Open the ColdFusion Administrator by clicking on the Administrator icon in the ColdFusion Program group and entering the Administrator password.
  2. Under Extensions, click Java Applets. The Java Applets page appears.
  3. Click the Register New Applet button. The Add/Registered Java Applet page appears.
  4. Enter options for the following settings:

    Setting
    Description
    Applet Name
    Applet name
    Code
    Name of the file that contains the applet subclass. Must be relative to the code base URL. The class extension is optional.
    Code Base
    Base URL of the applet: directory that contains the applet components. The applet class files must be located within the Web server root directory, such as http://servername/classes
    Archive
    File name for the applet archive
    Method
    Method name in the applet that returns a string value. You use the name in the NAME attribute of the cfapplet tag to populate a form variable with the method value. If the applet has no method, leave this field blank.
    Height
    Applet height, in pixels
    Width
    Applet width, in pixel
    VSpace
    Measurement, in pixels, for the space above and below the applet
    HSpace
    Measurement, in pixels, for the space on each side of the applet
    Align
    Applet alignment
    Not Supported Message
    Message to display if the user’s Web browser does not support Java applets. To override this message, specify a different one in the cfapplet tag notsupported attribute.
    Parameter Name
    Name for a required applet parameter, typically provided by the applet.
    Value
    Default value for parameter

  5. Click Submit.


Applet registration fields

The following table explains the applet registration fields:

Field | Description
Codebase | Enter the base URL of the applet: the directory that contains the applet components. The applet class files must be located within the Web browser root directory. Example: http://servername/classes
Code | The name of the file that contains the compiled applet. The filename is relative to the code base URL. The *.class file extension is not required.
Method | Enter the name of a method in the applet that returns a string value. If you specify the method name in the cfapplet tag name attribute, the value returned by the method is available in the form’s action page as Form.name. If the applet has no method, leave this field blank.
Height | Enter a measurement in pixels for the vertical space for the applet.
Width | Enter a measurement in pixels for the horizontal space for the applet.
Vspace | Enter a measurement in pixels for the space above and below the applet.
Hspace | Enter a measurement in pixels for the space on each side of the applet.
Align | Select the alignment.
Not Supported Message | This message is displayed by browsers that do not support Java applets. To override this message, you specify a different message in the cfapplet notsupported attribute.
Parameter Name | Enter a name for a required applet parameter. Your Java applet typically provides the parameter name needed to use the applet. Enter each parameter in a separate parameter field.
Value | For every parameter that you enter, define a default value. Your applet documentation provides guidelines on valid entries.


Using cfapplet to embed an applet

After you register an applet, you can use the cfapplet tag to place the applet in a ColdFusion page. The cfapplet tag has two required attributes: appletsource and name. Because you registered the applet and you defined each applet parameter with a default value, you can invoke the applet with a very simple form of the cfapplet tag:

<cfapplet appletSource="appletname" name="form_variable">


Overriding alignment and positioning values

To override any of the values defined in the ColdFusion Administrator for the applet, you can use the optional cfapplet parameters to specify custom values. For example, the following cfapplet tag specifies custom spacing and alignment values:

<cfapplet appletSource="myapplet"
   name="applet1_var"
   height=400
   width=200
   vspace=125
   hspace=125
   align="left">


Overriding parameter values

You can also override the values that you assigned to applet parameters in the ColdFusion Administrator by providing new values for any parameter. In order to override a parameter, you must have already defined the parameter and a default value for it in the ColdFusion Administrator Applets page.

<cfapplet appletSource="myapplet"
   name="applet1_var"
   Param1="registered parameter1"
   Param2="registered parameter2">


Handling form variables from an applet

The cfapplet tag requires you to specify a form variable name for the applet. This variable, referenced like other ColdFusion form variables, Form.variable_name holds the value the applet method returns when it is executed in the cfform.

Not all Java applets return values. For instance, many graphical widgets do not return a specific value; they do their flipping, spinning, fading, exploding, and that is all. For this kind of applet, the method field in the Administrator remains empty. Other applets, however, do have a method that returns a value. You can only use one method for each applet that you register. If an applet includes more than one method that you want to access, you can register the applet with a unique name for each additional method you want to use.

To reference a Java applet return value in your application page:

  1. Specify the name of the method in the Add/Registered Java Applet page of the ColdFusion Administrator.
  2. Specify the method name in the name attribute of the cfapplet tag when you code your cfform.

When your page executes the applet, ColdFusion creates a form variable with the name that you specified. If you do not specify a method, ColdFusion does not create a form variable.


Input validation with cfform controls

The cfinput and cftextinput tags include the validate attributes, which lets you specify a valid data entry type for the control. You can validate user entries on the following data types:

Data type | Description
Date | Verifies US date entry in the form mm/dd/yyyy (where the year can have one through four digits).
Eurodate | Verifies valid European date entry in the form dd/mm/yyyy (where the year can have one through four digits).
Time | Verifies a time entry in the form hh:mm:ss.
Float | Verifies a floating point entry.
Integer | Verifies an integer entry.
Telephone | Verifies a telephone entry. You must enter telephone data as ###-###-####. You can replace the hyphen separator (-) with a blank. The area code and exchange must begin with a digit between 1 and 9.
Zipcode | (U.S. formats only) Number can be a five-digit or nine-digit zip in the form #####-####. You can replace the hyphen separator (-) with a blank.
Creditcard | Blanks and dashes are stripped and the number is verified using the mod10 algorithm.
Social_security_number | You must enter the number as ###-##-####. You can replace the hyphen separator (-) with a blank.
Regular_expression | Matches the input against a JavaScript regular expression pattern. You must use the pattern attribute to specify the regular expression. Any entry containing characters that matches the pattern is valid.

When you specify an input type in the validate attribute, ColdFusion tests for the specified input type when you submit the form, and submits form data only on a successful match. A successful form submission returns the value True and returns the value False if validation fails.


Validating with regular expressions

You can use regular expressions to match and validate the text that users enter in cfinput and cftextinput tags. Ordinary characters are combined with special characters to define the match pattern. The validation succeeds only if the user input matches the pattern.

Regular expressions allow you to check input text for a wide variety of conditions. For example, if a date field must only contain dates between 1950 and 2050, you can create a regular expression that matches only numbers in that range. You can concatenate simple regular expressions into complex search criteria to validate against complex patterns, such as any of several words with different endings.

You can use ColdFusion variables and functions in regular expressions. The ColdFusion Server evaluates the variables and functions before the regular expression is evaluated. For example, you can validate against a value that you generate dynamically from other input data or database values.

Note: The rules listed in this section are for JavaScript regular expressions, and apply to the regular expressions used in cfinput and cftextinput tags only. These rules differ from those used by the ColdFusion functions REFind, REReplace, REFindNoCase, and REReplaceNoCase. For information on regular expressions used in ColdFusion functions, see Using Regular Expressions in Functions.


Special characters

Because special characters are the operators in regular expressions, in order to represent a special character as an ordinary one, you must precede it with a backslash. For example, use a double backslash (\\) to represent a backslash.


Single-character regular expressions

The following rules govern regular expressions that match a single character:

  • Special characters are: + * ? . [ ^ $ ( ) { | \
  • Any character that is not a special character or escaped by being preceded by the backslash (\) matches itself.
  • A backslash (\) followed by any special character matches the literal character itself, that is, the backslash escapes the special character.
  • A period (.) matches any character except newline.
  • A set of characters enclosed in brackets ([]) is a one-character regular expression that matches any of the characters in that set. For example, "[akm]" matches an "a", "k", or "m". Note that if you want to include ] (closing square bracket) in square brackets it must be the first character. Otherwise, it does not work even if you use \].
  • A dash can indicate a range of characters. For example, "[a-z]" matches any lowercase letter.
  • If the first character of a set of characters in bracket is the caret (^), the expression matches any character except those in the set. It does not match the empty string. For example: [^akm] matches any character except "a", "k", or "m". The caret loses its special meaning if it is not the first character of the set.
  • You can make regular expressions case insensitive by substituting individual characters with character sets, for example, [Nn][Ii][Cc][Kk].
  • You can use the following escape sequences to match specific characters or character classes:

    Escape Seq

    Matches
    Escape Seq

    Meaning
    [\b]
    Backspace
    \s
    Any of the following white space characters: space, tab, form feed, and line feed.
    \b
    A word boundary such as a
    space
    \S
    Any character except the white space characters matched by \s
    \B
    A non-word boundary
    \t
    Tab
    \cX
    The control character Ctrl-x. For example, \cv matches Ctrl-v, the usual control character for
    pasting text.
    \v
    Vertical tab
    \d
    A digit character [0-9]
    \w
    An alphanumeric character or underscore. The equivalent of [A-Za-z0-9_]
    \D
    Any character except a digit
    \W
    Any character not matched by \w. The equivalent of [^A-Za-z0-9_]
    \f
    Form feed
    \n
    Backreference to the nth expression in parentheses. See Backreferences
    \n
    Line feed
    \ooctal
    The character represented in the ASII character table by the specified octal number
    \r
    Carriage return
    \xhex
    The character represented in the ASCII character table by the specified hexadecimal number


Multicharacter regular expressions

Use the following rules to build a multicharacter regular expression:

  • Parentheses group parts of regular expressions together into a subexpression that can be treated as a single unit. For example, (ha)+ matches one or more instances of "ha".
  • A one-character regular expression or grouped subexpression followed by an asterisk (*) matches zero or more occurrences of the regular expression. For example, [a-z]* matches zero or more lowercase characters.
  • A one-character regular expression or grouped subexpression followed by a plus (+) matches one or more occurrences of the regular expression. For example, [a-z]+ matches one or more lowercase characters.
  • A one-character regular expression or grouped subexpression followed by a question mark (?) matches zero or one occurrences of the regular expression. For example, xy?z matches either "xyz" or "xz".
  • The carat (^) at the beginning of a regular expression matches the beginning of the field.
  • The dollar sign ($) at the end of a regular expression matches the end of the field.
  • The concatenation of regular expressions creates a regular expression that matches the corresponding concatenation of strings. For example, [A-Z][a-z]* matches any capitalized word.
  • The OR character (|) allows a choice between two regular expressions. For example, jell(y|ies) matches either "jelly" or "jellies".
  • Braces ({}) are used to indicate a range of occurrences of a regular expression, in the form {m, n} where m is a positive integer equal to or greater than zero indicating the start of the range and n is equal to or greater than m, indicating the end of the range. For example, (ba){0,3} matches up to three pairs of the expression "ba". The form {m,} requires at least m occurrences of the preceding regular expression. The form {m} requires exactly m occurrences of the preceding regular expression. The syntax {,n} is not allowed.


Backreferences

Backreferencing lets you match text in previously matched sets of parentheses. A slash followed by a digit n (\n) refers to the nth parenthesized subexpression.

One example of how you can use backreferencing is searching for doubled words; for example, to find instances of ‘the the’ or ‘is is’ in text. The following example shows the syntax you use for backreferencing in regular expressions:

(\b[A-Za-z]+)[ ]+\1

This code matches text that contains a word (specified by the \b word boundary special character and the [A-Za-z]+) followed by one or more spaces [ ]+, followed by the first matched subexpression in parentheses. For example, it would match “is is, or “This is is”, but not “This is”.


Exact and partial matches

Entered data is normally valid if any of it matches the regular expression pattern. Often you might ensure that the entire entry matches the pattern. If so, you must “anchor” it to the beginning and end of the field as follows:

  • If a caret (^) is at the beginning of a pattern, the field must begin with a string that matches the pattern.
  • If a dollar sign ($) is at the end of pattern, the field must end with a string that matches the pattern.
  • If the expression starts with a caret and ends with a dollar sign, the field must exactly match the pattern.


Expression examples

The following examples show some regular expressions and describe what they match:

Expression
Description
[\?&]value=
Any string containing a URL parameter value.
^[A-Z]:(\\[A-Z0-9_]+)+$
An uppercase DOS/Windows directory path that is not the root of a drive and has only letters, numbers, and underscores in its text.
^(\+|-)?[1-9][0-9]*$
An integer that does not begin with a zero and has an optional sign.
^(\+|-)?[1-9][0-9]*(\.[0-9]*)?$
A real number.
^(\+|-)?[1-9]\.[0-9]*E(\+|-)?[0-9]+$
A real number in engineering notation.
a{2,4}
A string containing two to four occurrences of 'a': aa, aaa, aaaa; for example aardvark, but not automatic.
(ba){2,}
A string containing least two 'ba' pairs; for example Ali baba, but not Ali Baba.


Resources

An excellent reference on regular expressions is Mastering Regular Expressions by Jeffrey E.F. Friedl, published by O'Reilly & Associates, Inc.


Input validation with JavaScript

In addition to native ColdFusion input validation using the validate attribute of the cfinput and cftextinput tags, the following tags support the onvalidate attribute, which lets you specify a JavaScript function to handle your cfform input validation:

  • cfgrid
  • cfinput
  • cfslider
  • cftextinput
  • cftree

ColdFusion passes the following arguments to the JavaScript function you specify in the onvalidate attribute:

  • The form object
  • The JavaScript input object corresponding to the tag whose value is being validated
  • The value of the control to validate

For example, if you code the cfinput tag as the following:

<cfinput type="text"
   ...
<!--- Do not include () in JavaScript function name --->
   onvalidate="handleValidation"
   ...
>

You define the JavaScript function as:

<script>
<!--
function handleValidation(form_object, input_object, object_value) {
...
}
//-->
</script>


Handling failed validation

The onerror attribute lets you specify a JavaScript function to execute if a validation fails. For example, if you use the onvalidate attribute to specify a JavaScript function to handle input validation, you can also use the onerror attribute to specify a JavaScript function to handle a failed validation (that is, when onvalidate returns a false value). If you use the validate attribute, you can also use the onerror attribute to specify a JavaScript function handle validation errors. The following cfform tags support the onerror attribute:

  • cfgrid
  • cfinput
  • cfselect
  • cfslider
  • cftextinput
  • cftree

ColdFusion passes the following JavaScript objects to the function in the onerror attribute:

  • form_object
  • input_object
  • object_value
  • error message text


Example: validating an e-mail address

The following example validates an e-mail entry. If the string is invalid, it displays a message box. If the address is valid, it redisplays the page. To be valid, the e-mail address must not be an empty string, contain an at sign (@) that is at least the second character, and contain a period (.) that is at least the fourth character.

To use JavaScript to validate form data:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>JavaScript Validation</title>

<script>
<!--
function testbox(form, ctrl, value) {
   if (value == "" || value.indexOf ('@', 1) == -1 ||
value.indexOf ('.', 3) == -1)
   {
      return (false);
   }
   else
   {
      return (true);
   }
}
//-->
</script>

</head>

<body>
<h2>JavaScript validation test</h2>

<p>Please enter your email address:</p>
<cfform name="UpdateForm" preservedata="Yes"
   action="validjs.cfm" >

   <cfinput type="text"
      name="inputbox1"
      required="YES"
      onvalidate="testbox"
      message="Sorry, your entry is not a valid email address."
      size="15"
      maxlength="30">

<input type="Submit" value=" Update... ">
</cfform>

</body>
</html>
  2. Save the page as validjs.cfm.
  3. View validjs.cfm in your browser.


Reviewing the code

The following table describes the highlight code and its function:

Code
Description
<script>
<!--
function testbox(form) {
Ctrl = Form.inputbox1;
   if (Ctrl.value == "" ||
      Ctrl.value.indexOf ('@', 1) == -1 ||
      Ctrl.value.indexOf ('.', 3) == -1)
   {
      return (false);
   }
   else
   {
      return (true);
   }
}
//-->
</script>
JavaScript code that tests for valid entry in the text box. The if statement checks to making sure that the field is not empty and contains an at sign (@) that at least the second character and a period (.) that is at least the fourth character.
onvalidate="testbox"
Calls the JavaScript testbox function to validate entries in this control.
message="Sorry, your entry is not a valid
   email address."
Displays a message if the validation function returns a false value.

Previous


Charting and Graphing Data

This chapter explains how to use the cfchart tag to display charts and graphs. It describes ways that you can chart data and gives you the tools you need to create effective charts.

Contents
  • Creating a chart
  • Administering charts
  • Charting data
  • Controlling chart appearance
  • Linking charts to URLs
Next


Creating a chart

The ability to display data in a chart or graph can make data interpretation much easier. Rather than present a simple table of numeric data, you can display a bar, pie, line, or other applicable type of chart using colors, captions, and a two-dimensional or three-dimensional representation of your data.

The cfchart tag, along with the tags cfchartseries and cfchartdata, provide many different chart types. The attributes to these tags let you customize your chart appearance.


Chart types

You can create 11 types of charts in ColdFusion in two and three dimensions. The following figure shows a sample of each type of chart in two dimensions.

Note: Horizontal bar charts are bar charts rotated 90 degrees. In two dimensions, bar and cylinder charts appear the same, as do cone and pyramid charts.

This is a picture of the feature being described.


Creating a basic chart

To create a chart, you use the cfchart tag along with at least one cfchartseries tag. You can optionally include one or more cfchartdata tags within a cfchartseries tag. The following table describes these tags:

Tag | Description
cfchart | Specifies the container in which the chart appears. This container defines the height, width, background color, labels, fonts, and other characteristics of the chart. You must include at least one cfchartseries tag within the cfchart tag.
cfchartseries | Specifies a database query that supplies the data to the chart and/or one or more cfchartdata tags specifying individual data points. Specifies the chart type, colors for the chart, and other optional attributes.
cfchartdata | Optionally specifies individual data point to the cfchartseries tag.

The following shows the basic code you use to create a chart:

<cfchart
   <!--- optional attributes to cfchart --->
   >

   <!--- one or more cfchartseries tags --->
   <cfchartseries
      type="type"
      <!--- optional attributes to cfchartseries --->
      />

   <cfchartseries
      type="type"
      <!--- optional attributes to cfchartseries --->
      >
         <!--- zero or more cfchartdata tags --->
         <cfchartdata
            value="number"
            <!--- optional attributes to cfchartdata --->
            >
   </cfchartseries>

</chart>

Often, you use these tags to chart the data stored in a ColdFusion query. If you have a query that contains average salary information by department, the following code displays a bar chart that shows the data in the query:

<cfchart
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
   >
   <cfchartseries
      type="bar"
      query="DataTable"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      />
</cfchart>

In this example, the data from the query column AvgByDept supplies the data for the y-axis, and the query column Dept_Name provides the data for the x-axis.

The resulting chart looks like the following:

This is a picture of the feature being described.


Administering charts

Use the ColdFusion Administrator to administer charts. In the Administrator, you can choose to save cached charts in memory or to disk. You can also specify the number of charts to cache, the number of charting threads, and the disk file for caching images to disk.

ColdFusion caches charts as they are created. In that way, repeated requests of the same chart load the chart from the cache rather than having ColdFusion render the chart over and over again.

Note: You do not have to perform any special coding to reference a cached chart. Whenever you use the cfchart tag, ColdFusion inspects the cache to see if the chart has already been rendered. If so, ColdFusion loads the chart from the cache.

The following table describes the settings for the ColdFusion charting and graphing engine:

Option | Description
Cache Type | Set the cache type. Charts can be cached in memory or to disk. Caching in memory is faster, but more memory intensive.
Maximum number of images in cache | Specify the maximum number of charts to store in the cache. When the limit is reached, the oldest chart in the cache is deleted to make room for a new one. The maximum number of charts you can store in the cache is 250.
Max number of charting threads | Specify the maximum number of chart requests that can be processed concurrently. The minimum number is 1 and the maximum is 5. Higher numbers are more memory intensive.
Disk cache location | When caching to disk, specify the directory in which to store the generated charts.


Charting data

One of the most important considerations when you chart data is the way you supply the data to the cfchart tag. You can supply data in the following ways:

  • Provide all the data in a single query using cfchartseries tags.
  • Specify individual data points using cfchartdata tags.
  • Combine data from a query with additional data points from cfchartdata tags.

Note: The cfchart tag charts numeric data only. As a result, you must convert any dates, times, or preformatted currency values, such as $3,000.53, to integers or real numbers.


Charting a query

When you chart a query, you specify the query name using the query attribute of the cfchartseries tag. For example, the code for a simple bar chart might be as follows:

<cfchart
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
   >

   <cfchartseries
      type="bar"
      query="DataTable"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      />

</cfchart>

This example displays the values in the AvgByDept column of the DataTable query. It displays the Dept_Name column value as the item label by each bar.

You use the following attributes of the cfchartseries tag when working with queries:

Attribute | Description
query | The query that contains the data. You must also specify valueColumn and itemColumn.
valueColumn | The query column that contains the values to be charted.
itemColumn | The query column that contains the description for this data point. The item normally appears on the horizontal axis of bar and line charts, on the vertical axis of horizontal bar charts, and in the legend in pie charts.

Using queries of queries provides significant power in generating the data for the chart. For example, you can use aggregating functions such as SUM, AVG, and GROUP BY to create a query of queries with statistical data based on a raw database query. For more information, see Using Query of Queries.

You can also take advantage of the ability to reference and modify query data dynamically. For example, you can loop through the entries in a query column and reformat the data to show whole dollar values.

The example in the following procedure analyzes the salary data in the CompanyInfo database using a query of queries and displays the data as a bar chart.

To chart a query of queries:

  1. Create a new ColdFusion page with the following content:
    2. <!-- Get the raw data from the database. -->
<cfquery name="GetSalaries" datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID = Employee.Dept_ID
</cfquery>

<!-- Generate a query with statistical data for each department. -->
<cfquery dbtype = "query" name = "DeptSalaries">
   SELECT
      Dept_Name,
      AVG(Salary) AS AvgByDept
   FROM GetSalaries
   GROUP BY Dept_Name
</cfquery>

<!--- Reformat the generated numbers to show only thousands --->
<cfloop index="i" from="1" to="#DeptSalaries.RecordCount#">
   <cfset DeptSalaries.AvgByDept[i]=Round(DeptSalaries.AvgByDept[i]/1000)*1000>
</cfloop>

<html>
<head>
   <title>Employee Salary Analysis</title>
</head>

<body>
<h1>Employee Salary Analysis</h1>

<!--- Bar chart, from DeptSalaries Query of Queries --->
<cfchart
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
      font="Arial"
      gridlines=6
      showXGridlines="yes"
      showYGridlines="yes"
      showborder="yes"
      show3d="yes"
   >

   <cfchartseries
      type="bar"
      query="DeptSalaries"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      seriesColor="olive"
      paintStyle="plain"
   />
</cfchart>

<br>
</body>
</html>
  2. Save the page as chartdata.cfm in myapps under the Web root directory. For example, the directory path on Windows might be C:\Inetpub\wwwroot\myapps.
  3. Return to your browser and enter the following URL to view chartdata.cfm:

    4. http://127.0.0.1/myapps/chartdata.cfm

    The following figure appears:

    This is a picture of the feature being described.

Note: If a query contains two rows with the same value for the itemColumn, ColdFusion graphs the last row in the query for that value. For the previous example, if the query contains two rows for the Sales department, ColdFusion graphs the value for the last row in the query for Sales.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfquery name="GetSalaries"
datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID =
      Employee.Dept_ID
</cfquery>
Query the CompanyInfo database to get the Dept_Name and Salary for each employee. Because the Dept_Name is in the Departmt table and the Salary is in the Employee table, you need a table join in the WHERE clause. The raw results of this query could be used elsewhere on the page.
<cfquery dbtype = "query"
      name = "DeptSalaries">
   SELECT
      Dept_Name,
      AVG(Salary) AS AvgByDept
   FROM GetSalaries
   GROUP BY Dept_Name
</cfquery>
Generate a new query from the GetSalaries query. Use the AVG aggregating function to get statistical data on the employees. Use the GROUP BY statement to ensure that there is only one row for each department.
<cfloop index="i" from="1"

to="#DeptSalaries.RecordCount#">
   <cfset DeptSalaries.AvgByDept[i]=
   Round(DeptSalaries.AvgByDept[i]
   /1000)*1000>
</cfloop>
Loop through all the rows in DeptSalaries query and round the salary data to the nearest thousand. This loop uses the query variable RecordCount to get the number of rows and changes the contents of the query object directly.
<cfchart
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
      font="Arial"
      gridlines=6
      showXGridlines="yes"
      showYGridlines="yes"
      showborder="yes"
      show3d="yes" >
   <cfchartseries
      type="bar"
      query="DeptSalaries"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      seriesColor="olive"
      paintStyle="plain"/>
</cfchart>
Create a bar chart using the data from the AvgByDept column of the DeptSalaries query. Label the bars with the Department names.

You can also rewrite this example to use the cfoutput and cfchartdata tags within the cfchartseries tag, instead of using the loop, to round the salary data, as the following code shows:

<cfchartseries
   type="bar"
   seriesColor="olive"
   paintStyle="plain">

   <cfoutput query="deptSalaries">
      <cfchartdata item="#dept_name#" value=#Round(AvgByDept/1000)*1000#>
   </cfoutput>

</cfchartseries>


Charting individual data points

When you chart individual data points, you specify each data point by inserting a cfchartdata tag in the cfchartseries tag body. For example, the following code creates a simple pie chart:

<cfchart>
   <cfchartseries type="pie">
      <cfchartdata item="New Vehicle Sales" value=500000>
      <cfchartdata item="Used Vehicle Sales" value=250000>
      <cfchartdata item="Leasing" value=300000>
      <cfchartdata item="Service" value=400000>
   </cfchartseries>
</cfchart>

This pie chart displays four types of revenue for a car dealership. Each cfchartdata tag specifies a department’s income and description for the legend.

Note: If two data points have the same item name, ColdFusion graphs the value for the last one specified within the cfchart tag.

The cfchartdata tag lets you specify the following information about a data point:

Attribute | Description
value | The data value to be charted. This attribute is required.
item | (Optional) The description for this data point. The item appears on the horizontal axis of bar and line charts, on the vertical axis of horizontal bar charts, and in the legend in pie charts.


Combining a query and data points

To chart data from both query and individual data values, you specify the query name, and related attributes, in the cfchartseries tag, and provide additional data points using the cfchartdata tag.

ColdFusion displays the chart data specified by a cfchartdata tag before the data from a query; for example, to the left on a bar chart. You can use the sortXAxis attribute of cfchart to sort data alphabetically long the x-axis.

One use of combining queries and data points could be if the database is missing data for one department, you can add the information manually. The following example adds data for the Facilities and Documentation departments to the salary data obtained from the query shown in the previous section:

<cfchart

   <cfchartseries
      type="bar"
      query="DataTable"
      itemColumn ="Dept_Name"
      valueColumn="AvgByDept"
      >

      <cfchartdata item="Facilities" value="35000">
      <cfchartdata item="Documentation" value="725000">

   </cfchartseries>
</cfchart>


Charting multiple data collections

Sometimes, you might have more than one series of data to display on a single chart, or you want to compare two sets of data on the same chart. In some cases, you might want to use different charting types on the same chart. For example, you might want to include a line chart on a bar chart.

To combine multiple data series into a single chart, insert multiple cfchartseries tags within a single cfchart tag. You control how the multiple data collections are charted using the seriesPlacement attribute of the cfchart tag. Using this attribute, you can specify the following options:

  • default Let ColdFusion determine the best mehtod for combining the data.
  • cluster Place corresponding chart elements from each series next to each other.
  • stacked Combine the corresponding elements of each series.
  • percent Show the elements of each series as a percentage of the total of all corresponding elements.

The following figure shows these options for combining two bar charts:

This is a picture of the feature being described.

You can also combine chart types. The following is a combination bar and line chart:

This is a picture of the feature being described.

The only chart type that you cannot mix with others is the pie chart. If you define one of the data series to use a pie chart, no other chart will appear.

The following example creates the previous figure showing a bar chart with a line chart added to it. In this example, you chart the salary of permanent employees (bar) against contract employees (line).

Note: The layering of multiple series depends on the order that you specify the cfchartseries tags. For example, if a bar chart is specified first and a line chart second, the bar chart appears in front of the line chart in the final chart.

To create a combination bar and a line chart:

  1. Open chartdata.cfm in your editor.
  2. Edit the cfchart tag so that it appears as follows:
    3. <cfchart
      backgroundColor="white"
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
      font="Arial"
      gridlines=6
      showXGridlines="yes"
      showYGridlines="yes"
      showborder="yes"
   >

   <cfchartseries
      type="line"
      seriesColor="blue"
      paintStyle="plain"
      seriesLabel="Contract Salaries"
      >
         <cfchartdata item="HR" value=70000>
         <cfchartdata item="Marketing" value=95000>
         <cfchartdata item="Sales" value=80000>
         <cfchartdata item="Training" value=93000>
      </cfchartseries>

   <cfchartseries
      type="bar"
      query="DeptSalaries"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      seriesColor="gray"
      paintStyle="plain"
      seriesLabel="Dept. Average Salaries"
      />

</cfchart>
  3. Save the page as chart2queries.cfm in myapps under the web root directory. For example, the directory path on Windows might be C:\Inetpub\wwwroot\myapps.
  4. Return to your browser and enter the following URL to view chart2queries.cfm:

    5. http://127.0.0.1/myapps/chart2queries.cfm


Writing a chart to a variable

In some cases, your application might have charts that are static or charts that, because of the nature of the data input, take a long time to render. In this scenario, you can create a chart and write it to a variable.

Once written to a variable, other ColdFusion pages can access the variable to display the chart, or you can write the variable to disk to save the chart to a file. This lets you create or update charts only as needed, rather than every time someone requests a page containing a chart.

You use the name attribute of the cfchart tag to write a chart to a variable. If you specify the name attribute, the chart is not rendered in the browser but is written to the variable.

You can save the chart as a Flash movie (.swf file), or as a JPG or PNG image file. If you save the image as a Flash movie, you can pass the variable back to a Flash client using ColdFusion Flash Remoting. For more information, see Using the Flash Remoting service.

Note: If you write the chart to a JPG or PNG file, mouseover tips and URLs embedded in the chart for data drill-down will not work when you redisplay the image from the file. However, if you save the image a Flash movie, both tips and drill-down URLs will work. For more information on data drill-down, see Linking charts to URLs.

To write a chart to a variable and a file:

  1. Create a new ColdFusion page with the following content:
    2. <cfchart
   name="myChart"
   format="jpg"
   >

   <cfchartseries type="pie">
      <cfchartdata item="New Vehicle Sales" value=500000>
      <cfchartdata item="Used Vehicle Sales" value=250000>
      <cfchartdata item="Leasing" value=300000>
      <cfchartdata item="Service" value=400000>
   </cfchartseries>

</cfchart>

<cffile
   action="WRITE"
   charset="ISO-8859-1"
   file="c:\inetpub\wwwroot\charts\vehicle.jpg"
   output="#myChart#">
<img src="c:\inetpub\wwwroot\charts\vehicle.jpg"
   height=240

   width=320>
  1. Save the page as chartToFile.cfm in myapps under the web root directory.
  2. Return to your browser and enter the following URL to view chartToFile.cfm:

    3. http://127.0.0.1/myapps/chartToFile.cfm

    The chart is saved to disk as c:\inetpub\wwwroot\charts\vehicle.jpg


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
<cfchart
   name="myChart"
   format="jpg">
Define a chart written to the variable myChart using the JPG format.
<cffile
   action="WRITE"
   charset="ISO-8859-1"
   file=
      "c:\inetpub\wwwroot\charts\vehicle.jpg"
   output="#myChart#">
Use cffile to write the chart to a file.
You must specify a charset of ISO-8859-1 when writing binary chart data to a file.
<img
   src=
      "c:\inetpub\wwwroot\charts\vehicle.jpg"
   height=240
   width=320>
Use the HTML img tag to display the chart.


Controlling chart appearance

Use the cfchart and cfchartseries tags to customize the appearance of your charts.


Common chart characteristics

You can optionally specify the following characteristics to cfchart on all types of charts:

Chart characteristic

Attributes used

Description
File type
format
Whether to send the chart to the user as a JPG, PNG, or Flash Movie (.swf) file. Flash is the default format.
Dimensions
chartWidth
chartHeight
The width and height, in pixels, of the chart. This size defines the entire chart area, including the legend and background area around the chart.
The default height is 240 pixels; the default width is 320 pixels.
Column labels
sortXAxis
Specifies to display the column labels along the x-axis in alphabetical order. The default is no.
Foreground and background color
foregroundColor
dataBackgroundColor
backgroundColor
The colors used for foreground and background objects.
The default foreground color is black; the default background colors are white.
You can specify 16 color names or use any valid HTML color format. If you use the numeric format, you must use double pound signs, for example, blue or ##FF33CC. For the complete list of colors, see Administering ColdFusion MX.
Border
showBorder
Specifies to draw a border around the chart. The border color is the same as specified by the foregroundColor attribute. Default is no.
Labels
font
fontSize
fontBold
frontItalic
labelFormat
xAxisTitle
yAxisTitle
font specifies the font for all text. Default is Arial. If you are using a double-byte character set on UNIX, or using a double-byte character set on Windows with a file type of Flash, you must specify ArialUnicodeMs as the font.
fontSize speciofies an Integer font size used for all text. Default is 11.
fontBold specifies to display all text as bold. Default is no.
fontItalic specifies to display all text as italic. Default is no.
labelFormat specifies the format of the y-axis labels, number, currency, percent, or date. Default is number.
xAxisTitle and yAxisTitle specify the title for each axis.
3-D Appearance
show3D
xOffset
yOffset
Displays the chart in 3-D. Default is no.
Specifies the amount to which the chart should be rotated on a horizontal axis (xOffset) or vertical axis (yOffset). 0 is flat (no rotation), -1 and 1 are for a full 90 degree rotation left (-1) or right (1). Default is .1
Rotation
rotated
Rotates the entire chart 90 degrees. Set to yes to create a horizontal chart, such as a horizontal bar chart. Default is no.
Multiple series
showLegend
seriesPlacement
showLegend specifies to display the chart’s legend when the chart contains more than one series of data. Default is yes.
seriesPlacement specifies the location of each series relative to the others. By default, ColdFusion determines the best placement based on the graph type of each series.
Tips
tipStyle
tipBGColor
tipStyle specifies to display a small popup window that shows information about the chart element pointed to by the curser. Options are none, mousedown, or mouseover. Default is mouseover.
tipBGColor specifies the background color of the tip window for Flash format only. Default is white.
Markers
showMarkers
markerSize
showMarkers specifies to show markers at the data points for 2-D line, curve, and scatter charts. Default is yes.
markerSize specifies an integer number of pixels for the marker size. ColdFusion determines default.

You can also use the cfchartseries tag to specify attributes of chart appearance. The following table describes these attributes:

Chart characteristic | Attributes used | Description
Multiple series | seriesLabel seriesColor | seriesLabel specifies the text displayed for the series label. seriesColor specifies a single color of the bar, line, pyramid, and so on. For pie charts, this is the first slice's color. Subsequent slices are automatically colored based on the specified initial color, or use the colorList attribute.
Paint | paintStyle | Specifies the way color is applied to a data series. You can specify solid color, buttonized look, linear gradient fill with a light center and darker outer edge, and gradient fill on lighter version of color. Default is solid.
Data markers | markerStyle | For line, curve, and scatter charts, specifies the shape used to mark the data point. Supported for 2-dimensional charts. Default is rectangle.


Setting x-axis and y-axis characteristics

You can specify the following additional characteristics to control the look of the x-axis and y-axis of charts, except for pie charts:

Chart
characteristic

Attributes used

Description
Value axis
scaleFrom
scaleTo
The minimum and maximum points on the data axis.
By default the minimum is 0 or the lowest negative chart data value, and the maximum is the largest data value.
Grid lines
showXGridlines
showYGridlines
gridLines
showXGridlines and showYGridlines specify to display x-axis and y-axis grid lines. Default no for x-axis gridlines, and yes for y-axis gridlines.
gridLines specifies the total number of grid lines on the value axis, including the axis itself. The value of each grid line appears along the value axis. The cfchart tag displays horizontal grid lines only. A value of 0 (the default) means no grid lines.


Creating a bar chart

The example in the following procedure adds a title to the bar chart and changes its appearance from the default, flat look, to a 3-D look. It adds grid lines, sets the maximum y-axis value to 100,000, and uses a custom set of colors.

To enhance the bar chart:

  1. Open the chartdata.cfm file in your editor.
  2. Edit the cfchart tag so that it appears as follows:
    3. <!--- Bar chart, from Query of Queries --->
<cfchart

      scaleTo = 100000
      fontSize=16
      gridLines = 4
      show3D="yes"

   >

   <cfchartseries
      type="bar"
      query="DeptSalaries"
      valueColumn="AvgByDept"
      itemColumn="Dept_Name"
      />

</cfchart>
  1. Save the file.
  2. Return to your browser and enter the following URL to view chartdata.cfm:

    3. http://127.0.0.1/myapps/chartdata.cfm


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
scaleTo = 100000
Set the maximum value of the vertical axis to 100000. The minimum value is the default, 0.
fontSize=16
Make the point size of the labels 16 points.
gridLines = 4
Display four grid lines between the top and bottom of the chart.
show3D = "yes"
Show the chart in 3-D.


Setting pie chart characteristics

You can specify the following additional characteristics for pie charts:

Chart characteristic
Attributes used
Description
Slice style
(cfchart tag)
pieSliceStyle
Display pie chart as solid or sliced. Default is sliced.
Data point colors
(cfchartseries tag)
colorList
A comma-separated list of colors to use for each pie slice.
You can specify 16 color names or use any valid HTML color format. If you use the numeric format, you must use double pound signs, for example, blue or ##FF33CC. For the complete list of colors, see Administering ColdFusion MX.
If you specify fewer colors than data points, the colors repeat. If you specify more colors than data points, the extra colors are not used.

The example in the following procedure adds a pie chart to the page.

To create a pie chart:

  1. Open chartdata.cfm in your editor.
  2. Edit the DeptSalaries query and the cfloop code so that it appears as follows:
    3. <!--- A query to get statistical data for each department. --->
<cfquery dbtype = "query" name = "DeptSalaries">
   SELECT
      Dept_Name,
      SUM(Salary) AS SumByDept,
      AVG(Salary) AS AvgByDept
   FROM GetSalaries
   GROUP BY Dept_Name
</cfquery>

<!--- Reformat the generated numbers to show only thousands --->
<cfloop index="i" from="1" to="#DeptSalaries.RecordCount#">
   <cfset DeptSalaries.SumByDept[i]=Round(DeptSalaries.SumByDept[i]/
1000)*1000>
   <cfset DeptSalaries.AvgByDept[i]=Round(DeptSalaries.AvgByDept[i]/
1000)*1000>
</cfloop>
  3. Add the following cfchart tag:
    4. <!--- Pie chart, from DeptSalaries Query of Queries --->
<cfchart
      tipStyle="mousedown"
      font="Times"
      fontsize=14
      fontBold="yes"
      backgroundColor = "##CCFFFF"
      show3D="yes"
      >

   <cfchartseries
      type="pie"
      query="DeptSalaries"
      valueColumn="SumByDept"
      itemColumn="Dept_Name"
      colorlist="##6666FF,##66FF66,##FF6666,##66CCCC"
      />
</cfchart>
<br>
  4. Save the file.
  5. Return to your browser and enter the following URL to view chartdata.cfm:

    6. http://127.0.0.1/myapps/chartdata.cfm

    The following figure appears:

    This is a picture of the feature being described.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
SUM(Salary) AS SumByDept,
In the DeptSalaries query, add a SUM aggregation function to get the sum of all salaries per department.
<cfset DeptSalaries.SumByDept[i]=
   Round(DeptSalaries.SumByDept[i]/
   1000)*1000>
In the cfloop tag, round the salary sums to the nearest thousand.
<cfchart
   tipStyle="mousedown"
   font="Times"
   fontBold="yes"
   backgroundColor = "##CCFFFF"
   show3D="yes"
   >
Show a tip only when a user clicks on the chart, display text in Times Bold font, set the background color to light blue, and display the chart in 3-D.
<cfchartseries
   type="pie"
   query="DeptSalaries"
   valueColumn="SumByDept"
   itemColumn="Dept_Name"
   colorlist=
      "##6666FF,##66FF66,##FF6666,##66CCCC"
/>
Create a pie chart using the SumByDept salary sum values from the DeptSalares query.
Use the contents of the Dept_Name column for the item labels displayed in the chart legend.
Get the pie slice colors from a custom list, which uses hexadecimal color numbers. The double pound signs prevent ColdFusion from trying to interpret the color data as variable names.


Creating an area chart

The example in the following procedure adds an area chart showing the average salary by start date to the salaries analysis page. It shows the use of a second query of queries to generate a new analysis of the raw data from the GetSalaries query. It also shows the use of additional cfchart attributes.

To create an area chart:

  1. Open chartdata.cfm your editor.
  2. Edit the GetSalaries query so that it appears as follows:
    3. <!-- Get the raw data from the database. -->
<cfquery name="GetSalaries" datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.StartDate,
      Employee.Salary
   FROM Departmt, Employee
   WHERE Departmt.Dept_ID = Employee.Dept_ID
</cfquery>
  3. Add the following code before the html tag:
    4. <!--- Convert start date to start year. --->
<!--- You must explicitly convert the date to a number for the query to work
--->
<cfloop index="i" from="1" to="#GetSalaries.RecordCount#">
<cfset GetSalaries.StartDate[i]=NumberFormat(DatePart("yyyy",
GetSalaries.StartDate[i]) ,9999)>
</cfloop>

<!--- Query of Queries for average salary by start year --->
<cfquery dbtype = "query" name = "HireSalaries">
   SELECT
      StartDate,
      AVG(Salary) AS AvgByStart
   FROM GetSalaries
   GROUP BY StartDate
</cfquery>

<!--- Round average salaries to thousands --->
<cfloop index="i" from="1" to="#HireSalaries.RecordCount#">
   <cfset
HireSalaries.AvgByStart[i]=Round(HireSalaries.AvgByStart[i]/
1000)*1000>
</cfloop>
  4. Add the following cfchart tag before the end of the body tag block.
    5. <!--- Area-style Line chart, from HireSalaries Query of Queries --->
<cfchart
      chartWidth=400
      BackgroundColor="##FFFF00"
      show3D="yes"
   >
   <cfchartseries
      type="area"
      query="HireSalaries"
      valueColumn="AvgByStart"
      itemColumn="StartDate"
    />
</cfchart>
<br>
  5. Save the page.
  6. Return to your browser and enter the following URL to view chartdata.cfm:

    7. http://127.0.0.1/myapps/chartdata.cfm


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
Employee.StartDate,
Add the employee start date to the data in the GetSalaries query.
<cfloop index="i" from="1"
    to="#GetSalaries.RecordCount#">
  <cfset GetSalaries.StartDate[i]=
  NumberFormat(DatePart("yyyy",
  GetSalaries.StartDate[i]) ,9999)>
</cfloop>
Use a cfloop tag to extract the year of hire from each employee’s hire data, and convert the result to a four-digit number.
<cfquery dbtype = "query" name =
"HireSalaries">
  SELECT
       StartDate,
    AVG(Salary) AS AvgByStart
  FROM GetSalaries
  GROUP BY StartDate
</cfquery>
Create a second query from the GetSalaries query. This query contains the average salary for each start year.
<cfloop index="i" from="1"
   to="#HireSalaries.RecordCount#">
  <cfset HireSalaries.AvgByStart[i]
  =Round(HireSalaries.AvgByStart[i]
  /1000)*1000>
</cfloop>
Round the salaries to the nearest thousand.
<cfchart
      chartWidth=400
      BackgroundColor="##FFFF00"
      show3D="yes" >
   <cfchartseries
      type="area"
      query="HireSalaries"
      valueColumn="AvgByStart"
      itemColumn="StartDate"
    />
</cfchart>
Create a line chart using the HireSalaries query. Chart the average salaries against the start date.
Limit the chart width to 400 pixels, show the chart in 3-D, and set the background color to white.


Setting curve chart characteristics

Curves use the attributes already discussed. However, you should be aware that curve charts require a large amount of processing to render. For fastest performance, create them offline, write them to a file or variable, then reference them in your application pages. For information on creating offline charts, see Writing a chart to a variable.


Linking charts to URLs

ColdFusion provides a data drill-down capability with charts. This means you can click on an area of a chart, both the data and the legend areas, to request a URL. For example, if you have a pie chart and want a user to be able to select a pie wedge for more information, you can build that functionality into your chart.

You use the url attribute of the cfchart tag to specify the URL to open when a user clicks anywhere on the chart. For example, define a chart that opens the page moreinfo.cfm when a user clicks on the chart using the following code:

<cfchart
   xAxisTitle="Department"
   yAxisTitle="Salary Average"
   url="moreinfo.cfm"
   >

      <cfchartseries
         seriesLable="Department Salaries"
      ...
      />

</cfchart>

You can use the following variables in the url attribute to pass additional information to the target page:

  • $VALUE$ The value of the selected item, or an empty string
  • $ITEMLABEL$ The label of the selected item, or an empty string
  • $SERIESLABEL$ The label of the selected series, or empty string

For example, to let users click on the graph to open the page moreinfo.cfm, and pass all three values to the page, you code the url attribute as follows:

url="moreinfo.cfm?Series=$SERIESLABEL$&Item=$ITEMLABEL$&Value=$VALUE$"

The variables are not enclosed in # signs like ordinary ColdFusion variables. They are enclosed in dollar signs. Clicking on a chart that uses this url attribute value could generate a URL in the following form:

http://localhost:8500/tests/charts/moreinfo.cfm?
Series=Department%20Salaries&Item=Training&Value=86000

You can also use JavaScript in the URL to execute client-side scripts. For an example, see Linking to JavaScript from a pie chart.


Dynamically linking from a pie chart

In the following example, when you click a pie wedge, ColdFusion displays a table that contains the detailed salary information for the departments represented by the wedge. The example is divided into two parts: creating the detail page and making the pie chart dynamic.

Part 1: creating the detail page

This page displays salary information for the department you selected when you click on a wedge of the pie chart. The department name is passed to this page using the $ITEMLABEL$ variable.

  1. Create a new application page with the following content:
    2. <cfquery name="GetSalaryDetails" datasource="CompanyInfo">
   SELECT Departmt.Dept_Name,
      Employee.FirstName,
      Employee.LastName,
      Employee.StartDate,
      Employee.Salary,
      Employee.Contract
   FROM Departmt, Employee
   WHERE Departmt.Dept_Name = '#URL.Item#'
   AND Departmt.Dept_ID = Employee.Dept_ID
   ORDER BY Employee.LastName, Employee.Firstname
</cfquery>

<html>
<head>
   <title>Employee Salary Details</title>
</head>

<body>

<h1><cfoutput>#GetSalaryDetails.Dept_Name[1]# Department
Salary Details</cfoutput></h1>
<table border cellspacing=0 cellpadding=5>
<tr>
   <th>Employee Name</th>
   <th>StartDate</th>
   <th>Salary</th>
   <th>Contract?</th>
</tr>
<cfoutput query="GetSalaryDetails" >
<tr>
   <td>#FirstName# #LastName#</td>
   <td>#dateFormat(StartDate, "mm/dd/yyyy")#</td>
   <td>#numberFormat(Salary, "$999,999")#</td>
   <td>#Contract#</td>
</tr>
</cfoutput>
</table>
</body>
</html>
  2. Save the page as Salary_details.cfm in myapps under the web root directory.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfquery name="GetSalaryDetails"
      datasource="CompanyInfo">
   SELECT
      Departmt.Dept_Name,
      Employee.FirstName,
      Employee.LastName,
      Employee.StartDate,
      Employee.Salary,
      Employee.Contract
   FROM Departmt, Employee
   WHERE
      Departmt.Dept_Name =
         '#URL.Item#'
   AND Departmt.Dept_ID =
      Employee.Dept_ID
   ORDER BY Employee.LastName,
      Employee.Firstname
</cfquery>
Get the salary data for the department whose name was passed in the URL parameter string. Sort the data by the employee’s last and first names.
<table border cellspacing=0 cellpadding=5>
<tr>
   <th>Employee Name</td>
   <th>StartDate</td>
   <th>Salary</td>
   <th>Contract?</td>
</tr>
<cfoutput query="GetSalaryDetails" >
<tr>
   <td>#FirstName# #LastName#</td>
   <td>#dateFormat(StartDate,
      "mm/dd/yyyy")#</td>
   <td>#numberFormat(Salary, "$999,999")#</td>
   <td>#Contract#</td>
</tr>
</cfoutput>
</table>
Display the data retrieved by the query as a table. Format the start date into standard month/date/year format, and format the salary with a leading dollar sign comma separator, and no decimal places.

Part 2: making the chart dynamic

  1. Open chartdata.cfm in your editor.
  2. Edit the cfchart tag for the pie chart so it appears as follows:
    3. <cfchart
      font="Times"
      fontBold="yes"
      backgroundColor="##CCFFFF"
      show3D="yes"
      url="Salary_Details.cfm?Item=$ITEMLABEL$"
      >

   <cfchartseries
      type="pie"
      query="DeptSalaries"
      valueColumn="SumByDept"
      itemColumn="Dept_Name"
      colorlist="##6666FF,##66FF66,##FF6666,##66CCCC"
   />
</cfchart>
  3. Save the file.
  4. Return to your browser and enter the following URL to view chartdata.cfm:

    5. http://127.0.0.1/myapps/chartdata.cfm

  5. Click the slices of the pie chart to request Salary_details.cfm and pass in the department name of the wedge you clicked. The salary information for that department appears.


Reviewing the code

The following table describes the highlighted code and its function:

Code
Description
url=
   "Salary_Details.cfm?Item=$ITEMLABEL$"
When the user clicks a wedge of the pie chart, call the Salary_Details.cfm page in the current directory, and pass it the parameter named Item containing the department name of the selected wedge.


Linking to JavaScript from a pie chart

In the following example, when you click a pie wedge, ColdFusion uses JavaScript to display a pop-up window about the wedge.

Create a dynamic chart using JavaScript

  1. Create a new application page with the following content:
    2. <script>
function Chart_OnClick(theSeries, theItem, theValue){
alert("Series: " + theSeries + ", Item: " + theItem + ", Value: " + theValue);
   }
</script>

<cfchart
      xAxisTitle="Department"
      yAxisTitle="Salary Average"
      tipstyle=none
      url="javascript:Chart_OnClick('$SERIESLABEL$','$ITEMLABEL$','$VALUE$');"
   >
   <cfchartseries type="bar" seriesLabel="Average Salaries by Department">
      <cfchartData item="Finance" value="75000">
      <cfchartData item="Sales" value="120000">
      <cfchartData item="IT" value="83000">
      <cfchartData item="Facilities" value="45000">
   </cfchartseries>
</cfchart>
  2. Save the page as chartdata_withJS.cfm in myapps under the Web root directory.
  3. Return to your browser and enter the following URL to view chartdata_withJS.cfm:

    4. http://127.0.0.1/myapps/chartdata_withJS.cfm

  4. Click the slices of the pie chart to display the pop-up window.
Previous


Using the Flash Remoting service

Using the Flash Remoting service of Macromedia ColdFusion MX, ColdFusion developers can work together with Macromedia Flash MX designers to build dynamic Flash user interfaces for ColdFusion applications.

Contents
  • About using the Flash Remoting service with ColdFusion
  • Using the Flash Remoting service with ColdFusion pages
  • Using Flash with ColdFusion components
  • Using the Flash Remoting service with server-side ActionScript
  • Using the Flash Remoting service with ColdFusion Java objects
Next


About using the Flash Remoting service with ColdFusion

Using the Flash Remoting service of ColdFusion MX, ColdFusion developers can work together with Macromedia Flash MX designers to build Flash UIs for ColdFusion applications. Building Flash UIs requires the separation of UI code from business logic code. User interface controls are built in Flash MX, while business logic is built in ColdFusion.

The following figure displays a simplified representation of the relationship between Flash and ColdFusion:

This is a picture of the feature being described.


Planning your Flash application

When planning ColdFusion application development with Flash UIs, remember the importance of separating display code from business logic. Separating display code, such as HTML, from business logic, such as CFML, enables your ColdFusion applications to interact with multiple client types, such as Flash movies, Web browsers, and web services.

Building ColdFusion applications for multiple clients means that your ColdFusion pages and components return common data types, including strings, integers, query objects, structures, and arrays. Clients that receive the results can process the passed data according to the client type, such as ActionScript with Flash or CFML with ColdFusion.

To use the Macromedia Flash Remoting service with Macromedia ColdFusion MX, you build ColdFusion pages and components or deploy Java objects. In ColdFusion pages, you use the Flash variable scope to interact with Flash applications. ColdFusion components natively support Flash interaction. In addition, you can use ColdFusion’s server-side ActionScript functionality, which lets you query databases and perform HTTP operations in ActionScript files on the server. The public methods of Java objects are also available to the Flash Remoting service.

The following sections explain developing Flash applications with ColdFusion:

  • Using the Flash Remoting service with ColdFusion pages
  • Using Flash with ColdFusion components
  • Using the Flash Remoting service with server-side ActionScript
  • Using the Flash Remoting service with ColdFusion Java objects
  • Handling errors with ColdFusion and Flash


Using the Flash Remoting service with ColdFusion pages

When building a ColdFusion page that interacts with Flash movies, the directory name that contains the ColdFusion pages translates to the Flash service name in ActionScript. The individual ColdFusion page names contained in that directory translate to service functions in ActionScript.

In your CFML, you use the Flash variable scope to access parameters passed from Flash movies and return values to Flash movies. To access parameters passed from Flash movies, you use the parameter name appended to the Flash variable or the Flash.Params array. To return values to the Flash application, use the Flash.Result variable. To set an increment value for records to be returned to the Flash application, use the Flash.Pagesize variable.

The following table shows the variables contained in the Flash scope:

Variable
Description
For more information
Flash.Params
A structure containing the parameters passed from the Flash movie.
See Accessing parameters passed from Flash.
Flash.Result
The variable returned to the Flash movie that called the function.
See Returning results to Flash.
Flash.Pagesize
The number of records returned at a time to Flash.
See Returning records in increments to Flash.

In addition, the following table compares the ColdFusion data types and their ActionScript equivalents:

ActionScript data type | ColdFusion MX data type
Number (primitive data type) | Number
boolean (primitive data type) | boolean
String | String
ActionScript (AS) object | Structure
AS Object (as the only argument passed to a service function) | Arguments to the service function. ColdFusion pages (.cfm): flash variable scope, ColdFusion components (.cfc): named arguments
null | null (ASC returns 0, which translates to not defined)
undefined | null (ASC returns 0, which translates to not defined)
Ordered array | Array
Named array | Struct
Date object | Date
XML object | XML document
RecordSet | Query object


Accessing parameters passed from Flash

To access variables passed from Flash movies, you append the parameter name to the Flash scope or use the Flash.Params array. Depending on how the values were passed from Flash, you refer to array values using ordered array syntax or structure name syntax. Only ActionScript objects can pass named parameters.

For example, if you pass the parameters as an ordered array from Flash, array[1] references the first value. If you pass the parameters as named parameters, you use standard structure-name syntax like params.name.

You can use most of the CFML array and structure functions on ActionScript collections. However, the StructCopy CFML function does not work with ActionScript collections. The following table describes the collections and examples.

Collection
ActionScript example
Notes
Strict array
var myArray = new Array();
myArray[1] = "one";
myArray[2] = "two";
myService.myMethod(myArray);
The Flash Remoting service converts the array argument to a ColdFusion MX array. All CFML array operations work as expected.
Named or associative array
var myStruct = new Array();
myStruct["one"] = "banana";
myStruct["two"] = "orange";
In ActionScript, named array keys are not case sensitive.
Mixed array
var myMixedArray = new Array();
myMixedArray["one"] = 1;
myMixedArray[2] = true;
Treat this collection like a structure in ColdFusion MX. However, keys that start with numbers are invalid CFML variable names. Depending on how you attempt to retrieve this data, ColdFusion MX might throw an exception. The following ColdFusion component example throws an exception:
<cfargument name="ca" type="struct">
<cfreturn ca.2>
The following ColdFusion component example does not throw an exception:
<cfargument name="ca" type="struct">
<cfreturn ca["2"]>
Using an ActionScript object initializer for named arguments
myService.myMethod({ x:1, Y:2, z:3
});
This notation provides a convenient way of passing named arguments to a ColdFusion MX-based Flash Remoting service. You can access these arguments in ColdFusion pages as members of the Flash scope, or as normal named arguments of a ColdFusion component function

The Flash.Params array retains the order of the parameters as they were passed to the function. You use standard structure name syntax to reference the parameters; for example:

<cfquery name="flashQuery" datasource="exampleapps" dbtype="ODBC">
   SELECT ItemName, ItemDescription, ItemCost
   FROM tblItems
   WHERE ItemName EQ '#Flash.paramName#'
</cfquery>

In this example, the query results are filtered by the value of Flash.paramName, which references the first parameter in the array. If the parameters were passed as an ordered array from Flash, you use standard structure name syntax; for example:

<cfset flash.result = "Variable 1:#Flash.params[1]#, Variable 2:
#Flash.params[2]#">

In this ActionScript example, notice that ActionScript starts the array index at zero. ColdFusion array indexes start at one.


Returning results to Flash

In ColdFusion pages, only the value of Flash.Result variable is returned to the Flash application. For more information about supported data types between ColdFusion and Flash, see the data type table in Using the Flash Remoting service with ColdFusion pages. The following procedure creates the service function helloWorld, which returns a structure containing simple messages to the Flash application.

To create a ColdFusion page that passes a structure to Flash:

  1. Create a folder in your web root, and name it helloExamples.
  2. Create a ColdFusion page, and save it as helloWorld.cfm in the helloExamples directory.
  3. Modify helloWorld.cfm so that the CFML code appears as follows:
    4. <cfset tempStruct = StructNew()>
<cfset tempStruct.timeVar = DateFormat(Now ())>
<cfset tempStruct.helloMessage = "Hello World">
  4. In the example, two string variables are added to a structure, one with a formatted date and one with a simple message. The structure is passed back to the Flash application using the Flash.Result variable.
  5. Save the file.

Remember, the directory name is used the service address, and the helloWorld.cfm file is a method of the helloExamples Flash Remoting service. The following ActionScript example calls the helloWorld ColdFusion page:

include "NetServices.as"
NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/gateway");
gatewayConnection = NetServices.createGatewayConnection();
CFMService = gatewayConnection.getService("helloExamples", this);
CFMService.helloWorld();

Note: Due to ActionScript's automatic type conversion, do not return a boolean literal to Flash from ColdFusion. Return 1 to indicate true, and return 0 to indicate false.


Returning records in increments to Flash

ColdFusion lets you return record set results to Flash in increments. For example, if a query returns 20 records, you can set the Flash.Pagesize variable to return five records at a time to Flash. Incremental record sets lets you minimize the time that Flash application waits for the application server data to load.

To create a ColdFusion page that returns a incremental record set to Flash:

  1. Create a ColdFusion page, and save it as getData.cfm in the helloExamples directory.
  2. Modify getData.cfm so that the code appears as follows:
    3. <cfparam name="pagesize" default="10">
<cfif IsDefined("Flash.Params")>
   <cfset pagesize = Flash.Params[1]>
</cfif>
<cfquery name="myQuery" datasource="ExampleApps">
   SELECT *
   FROM tblParks
</cfquery>
<cfset Flash.Pagesize = pagesize>
<cfset Flash.Result = myQuery>

In this example, if a single parameter is passed from the Flash application, the pagesize variable is set to the value of the Flash.Params[1] variable, otherwise the default is set to 10. Next, a cfquery statement queries the database. After that, the pagesize variable is assigned into the Flash.Pagesize variable. Finally, the query results are assigned into the Flash.Result variable, which is returned to Flash.
  3. Save your work.

When you assign a value to the Flash.Pagesize variable, you are specifying that if the record set has more than a certain number of records, the record set becomes pageable and returns the number of records specified in the Flash.Pagesize. For example:

include "NetServices.as"
NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/gateway");
gatewayConnection = NetServices.createGatewayConnection();
CFMService = gatewayConnection.getService("helloExamples", this);
CFMService.getData();

After the initial delivery of records, the RecordSet ActionScript class becomes responsible for fetching records. You can configure the client-side RecordSet object to fetch records in various ways using the setDeliveryMode ActionScript function.


Using Flash with ColdFusion components

ColdFusion components require little modification to work with Flash. The cffunction tag names the function and contains the CFML logic, and the cfreturn tag returns the result to Flash. The name of the ColdFusion component file (*.cfc) translates to the service name in ActionScript.

Note: For ColdFusion component methods to communicate with Flash movies, you must set the cffunction tag’s access attribute to remote.

The following example replicates the helloWorld function that was previously implemented as a ColdFusion page. For more information, see Using the Flash Remoting service with ColdFusion pages.

To create a ColdFusion component that interacts with a Flash movie:

  1. Create a ColdFusion component, and save it as flashComponent.cfc in the helloExamples directory.
  2. Modify the code in flashComponent.cfc so that it appears as follows:
    3. <cfcomponent name="flashComponent">
   <cffunction name="helloWorld" access="remote" returnType="Struct">
        <cfset tempStruct = StructNew()>
        <cfset tempStruct.timeVar = DateFormat(Now ())>
        <cfset tempStruct.helloMessage = "Hello World">
        <cfreturn tempStruct>
   </cffunction>
</cfcomponent>

In this example, the helloWorld function is created. The cfreturn tag returns the result to the Flash movie.
  3. Save the file.

The helloWorld service function is now available through the flashComponent service to ActionScript. The following ActionScript example calls this function:

#include "NetServices.as"
NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/gateway");
gatewayConnection = NetServices.createGatewayConnection();
CFCService = gatewayConnection.getService("flashExamples.flashComponent", this);
CFCService.helloWorld();

In this example, the getService references the flashComponent component in the flashExamples directory. You can now call the CFCService object sayHello and getTime functions.

For ColdFusion components, the component file name, including the directory structure from the web root, serves as the service name. Remember to delimit the path directories rather than backslashes.


Using component metadata with the Flash Remoting service

Flash MX designers can use the Service Browser in the Flash MX authoring environment to discover business logic functionality built in ColdFusion. You use the description attribute of the cffunction and cfargument tags to describe the ColdFusion functionality to the Service Browser.

To create a ColdFusion component that describes itself to the Service Browser:

  1. Open flashComponents.cfc, and modify the code so that it appears as follows:
    2. <cfcomponent name="flashComponent">
   <cffunction name="helloWorld" access="remote" returnType="Struct"
      description="Returns hello message">
      <cfset tempStruct = StructNew()>
      <cfset tempStruct.timeVar = DateFormat(Now ())>
      <cfset tempStruct.helloMessage = "Hello World">
      <cfreturn tempStruct>
   </cffunction>
</cfcomponent>

In this example, the description attribute of the cffunction tag supplies a short text description of the component method.
  2. Save the file.
  3. Open the Flash MX authoring environment, and open the Service Browser.
  4. If not already present, add your Flash Remoting service URL, such as http://localhost:8500/flashservices/gateway.
  5. To add the flashComponent service, enter helloExamples.flashComponent.
  6. When you click the getTime folder, the description appears in the Service Browser as shown in the following figure:
    This is a picture of the feature being described.
    .


Using the Flash Remoting service with server-side ActionScript

The ability to create server-side ActionScript provides a familiar way for Flash developers to access ColdFusion query and HTTP features without learning CFML. You can place ActionScript files (*.asr) on the server that you want to call from the Flash application anywhere below the web server’s root directory. To specify subdirectories of the webroot or a virtual directory, use package dot notation. For example, in the following assignment code, the stockquotes.asr file lives in the mydir/stock/ directory:

stockService = gatewayConnnection.getService("mydir.stock.stockquotes", this);

You can also point to virtual mappings, such as cfsuite.asr.stock.stockquotes, where cfsuite is a virtual mapping and asr.stock is a subdirectory of that mapping. The CF.query and CF.http functions give you a well-defined interface for building SQL queries and HTTP operations of ColdFusion.

For example, the following server-side ActionScript function definition returns a RecordSet object:

function basicQuery()
{
   mydata = CF.query({datasource:"customers",
      sql:"SELECT * FROM myTable"});
   return mydata;
}

Note: For more information about server-side ActionScript, see the Using Server-Side ActionScript in ColdFusion book.


Using the Flash Remoting service with ColdFusion Java objects

You can run various kinds of Java objects with ColdFusion MX, including JavaBeans, Java classes, and Enterprise JavaBeans. You can use the ColdFusion Administrator to add additional directories to the class path.

To add a directory to ColdFusion class path:

  1. Open the ColdFusion Administrator.
  2. In the Server Settings menu, click the Java and JVM link.
  3. Add your directory to the Class Path form field.
  4. Click Submit Changes.
  5. Restart ColdFusion.

When you place your Java files in the class path, the public methods of the class instance are available to your Flash movie.

For example, assume the Java class utils.UIComponents exists in a directory in your ColdFusion class path. The Java file contains the following code:

package utils;

public class UIComponents
{
 public String sayHello()
 {
  return "Hello";
 }
}

Note: You cannot call constructors with Flash Remoting. You must use the default constructor.

In ActionScript, the following getService call invokes the sayHello public method of the utils.UIComponents class:

#include "NetServices.as"
NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/gateway");
gatewayConnection = NetServices.createGatewayConnection();
javaService = gatewayConnection.getService("utils.UIComponents", this);
javaService.sayHello();
function sayHello_Result(result)
{
   trace(result);
}

Note: For more information about using Java objects with ColdFusion, see Using Java objects.


Handling errors with ColdFusion and Flash

To help with debugging, use the cftry and cfcatch tags to return error messages to the Flash Player, as in the following example:

<cftry>
   <cfset Flash.result = undefinedVar>
   <cfcatch>
      <cfset Flash.result="Failed">
   </cfcatch>
</cftry>

In this example, the first cfset tag fails to assign the value into Flash.Result because of an undefined variable.

Note: When you create a ColdFusion page that communicates with Flash, ensure that the ColdFusion page works before using it with Flash.

Previous


Using XML and WDDX

This chapter describes how to use ColdFusion to create, use, and manipulate XML documents. This chapter also presents Web Distributed Data Exchange (WDDX), an XML dialect for transmitting structured data, and describes how to use it to transfer data between applications and between CFML and JavaScript.

This chapter does not present XML concepts. Before you read this chapter you should become familiar with XML.

Contents
  • About XML and ColdFusion
  • The XML document object
  • ColdFusion XML tag and functions
  • Using an XML object
  • Creating and saving an XML document object
  • Modifying a ColdFusion XML object
  • Transforming documents with XSLT
  • Extracting data with XPath
  • Example: using XML in a ColdFusion application
  • Moving complex data across the web with WDDX
  • Using WDDX
Next


About XML and ColdFusion

In the last few years, XML has rapidly become the universal language for representing documents and data on the web. These documents can extend beyond the traditional concept of a paper document or its equivalent. For example, XML is often used to represent database or directory information. XML is also commonly used to represent transaction information, such as product orders or receipts, and for information such as inventory records and employee data.

Because XML represents data in a tagged, textual format it is an excellent tool for representing information that must be shared between otherwise-independent applications such as order entry and inventory management. No application needs to know anything about the other. Each application only needs to be prepared to get data in a format that is structured according to the XML DTD or Schema. For example, in a distributed order processing application, the order placement component, order fulfilment component, inventory management component, and billing component can all share information with each other in XML format. They could use a common XML DTD, of different components could communicate with each other using different DTDs.

After an application parses the XML document, it can then manipulate the information in any way that is appropriate. For example, you can convert tabular XML data into a ColdFusion recordset, perform queries on the data and then export the data an XML document. For example, the code in Example: using XML in a ColdFusion application takes a customer order in XML, converts the data to a recordset, and uses a query to determine the order cost. It then prepares a receipt as an XML document.

ColdFusion provides a comprehensive and easy-to-use set of tools for creating and using XML documents. ColdFusion lets you do the following with XML documents:

  • Convert XML text into ColdFusion XML document objects.
  • Create new ColdFusion XML document objects.
  • Modify ColdFusion XML document objects.
  • Transform XML using XSLT.
  • Extract data from XML documents using XPath expressions.
  • Convert ColdFusion XML document objects to text and save them in files.


The XML document object

ColdFusion represents an XML document as an object, called an XML document object, that is much like a standard ColdFusion structure. In fact, most ColdFusion structure functions, such as StructInsert, work with XML document objects. For a full list of ColdFusion functions that work on XML document objects, see Functions for XML object management.

You can look at the overall structure of an XML document in two ways: a basic view and a DOM (Document Object Model)-based node view. The basic view presents all the information in the document, but does not separate the data into as fine-grained units as the node view. ColdFusion can access XML document contents using either view.


A simple XML document

The next sections describe the basic and node views of the following simple XML document. This document is used in many of the examples in this chapter.

<?xml version="1.0" encoding="UTF-8"?>
<employee>
<!-- A list of employees -->
 <name EmpType="Regular">
  <first>Almanzo</first>
  <last>Wilder</last>
 </name>
 <name EmpType="Contract">
  <first>Laura</first>
  <last>Ingalls</last>
 </name>
</employee>


Basic view

The basic view of an XML document object presents the object as a container that holds one root element structure. The root element can have any number of nested element structures. Each element structure represents an XML tag (start tag/end tag set) and all its contents; it can contain additional element structures. A basic view of the simple XML document looks like the following:

This is a picture of the feature being described.


DOM node view

The DOM node view presents the XML document object using the same format as the document’s XML Document Object Model (DOM). In fact, an XML document object is a representation of a DOM object.

The DOM is a World Wide Web Consortium (W3C) recommendation (specification) for a platform- and language-neutral interface to dynamically access and update the content, structure, and style of documents. ColdFusion conforms to the DOM Level 2 Core specification, available at http://www.w3.org/TR/DOM-Level-2-Core.

In the DOM node view, the document consists of a hierarchical tree of nodes. Each node has a DOM node type, a node name, and a node value. Node types include Element, Comment, Text, and so on. The DOM structures the document object and each of the elements it contains into multiple nodes of different types, providing a finer-grained view of the document structure than the basic view. For example, if an XML comment is in the middle of a block of text, the DOM node view represents its position in the text while the basic view does not.

ColdFusion also allows you to use the DOM objects, methods, and properties defined in the W3C DOM Level 2 Core specification to manipulate the XML document object.

For more information on referencing DOM nodes, see XML DOM node structure. This document does not cover the node view and using DOM methods and properties in detail.


XML document structures

An XML document object is a structure that contains a set of nested XML element structures. The following figure shows the output of a cfdump tag that displays the document object for the XML in A simple XML document.The following figure shows the output of the cfdump tag:

This is a picture of the feature being described.

The following code displays this output. It assumes that you save the code in a file under your web root, such as C:\Inetpub\wwwroot\testdocs\employeesimple.xml

<cffile action="read" file="C:\Inetpub\wwwroot\testdocs\employeesimple.xml"
variable="xmldoc">
<cfset mydoc = XmlParse(xmldoc)>
<cfdump var="#mydoc#">


The document object structure

At the top level, the XML document object has the following three entries:

Entry name | Type | Description
XmlRoot | Element | The root element of the document.
XmlComment | String | A string made of the concatenation of all comments on the document, that is, comments in the document prologue and epilog. This string does not include comments inside document elements.
XmlDocType | XmlNode | The DocType attribute of the document. This entry only exists if the document specifies a DocType. This entry does not appear when cfdump displays an XML element structure.


The element structure

Each XML element has the following entries:

Entry name | Type | Description
XmlName | String | The name of the element.
XmlNsPrefix | String | The prefix of the Namespace.
XmlNsURI | String | The URI of the Namespace.
XmlText | String | A string made of the concatenation of all text and CData text in the element, but not inside any child elements.
XmlComment | String | A string made of the concatenation of all comments inside the XML element, but not inside any child elements.
XmlAttributes | Structure | All of this element’s attributes, as name-value pairs.
XmlChildren | Array | All this element’s children elements.
XmlParent | XmlNode | The parent DOM node of this element. This entry does not appear when cfdump displays an XML element structure.
XmlNodes | Array | An array of all the XmlNode DOM nodes contained in this element. This entry does not appear when cfdump displays an XML element structure.


XML DOM node structure

The following table lists the contents of an XML DOM node structure:

Entry name | Type | Description
XmlName | String | The node name. For nodes such as Element or Attribute, the node name is the element or attribute name.
XmlType | String | The node XML DOM type, such as Element or Text.
XmlValue | String | The node value. This entry is used only for Attribute, CDATA, Comment, and Text type nodes.

Note: cfdump does not display XmlNode structures. If you try to dump an XmlNode structure, cfdump displays “Empty Structure”.

The following table lists the contents of the XmlName and XmlValue fields for each node type that is valid in the XmlType entry. The node types correspond to the objects types in the XML DOM hierarchy.

Node type | XmlName | xmlValue
CDATA | #cdata-section | Content of the CDATA section
COMMENT | #comment | Content of the comment
ELEMENT | Tag name | Empty string
ENTITYREF | Name of entity referenced | Empty string
PI (processing instruction) | Target entire content excluding the target | Empty string
TEXT | #text | Content of the text node
ENTITY | Entity name | Empty string
NOTATION | Notation name | Empty string
DOCUMENT | #document | Empty string
FRAGMENT | #document-fragment | Empty string
DOCTYPE | Document type name | Empty string

Note: Although XML attributes are nodes on the DOM tree, ColdFusion does not expose them as XML DOM node data structures. To view an element’s attributes, use the element structure’s XMLAttributes structure.

The XML document object and all its elements are exposed as DOM node structures. For example, you can use the following variable names to reference nodes in the DOM tree created from the XML example in A simple XML document:

mydoc.XmlName
mydoc.XmlValue
mydoc.XmlRoot.XmlName
mydoc.employee.XmlType
mydoc.employee.XmlNodes[1].XmlType


ColdFusion XML tag and functions

The following table lists the ColdFusion tag (cfxml) and functions that create and manipulate XML documents

Tag or function
Description
<cfxml variable="objectName"
[caseSensitive="Boolean"]>
Creates a new ColdFusion XML document object consisting of the markup in the tag body. The tag can include XML and CFML tags. ColdFusion processes all CFML in the tag body before converting the resulting text to an XML document object.
If you specify the CaseSensitive="True"attribute, the case of names of elements and attributes in the document is meaningful. The default is False.
For more information on using the cfxml tag, see Creating a new XML document object using the cfxml tag.
XmlParse("XMLStringVar"
[, caseSensitive])
Converts an XML document that is represented as a string variable into an XML document object.
If you specify the optional second argument as True, the case of names of elements and attributes in the document is meaningful. The default is False.
For more information on using the XmlParse function, see Creating an XML document object from existing XML.
XmlNew([caseSensitive])
Returns a new, empty XML document object.
If you specify the optional argument as True, the case of names of elements and attributes in the document is meaningful. The default is False.
For more information on using the XmlNew function, seeCreating a new XML document object using the XmlNew function.
XmlElemNew(objectName,
"elementName")
Returns a new XML document object element with the specified name.
For more information on using the XmlElemNew function, see Adding an element.
XmlChildPos(element,
"elementName", position)
Returns the position (index) in an XmlChildren array of the Nth child with the specified element name. For example, XmlChildPos(mydoc.employee, "name", 2) returns the position in mydoc.employee.XmlChildren of the mydoc.employee.name[2] element. This index can be used in the ArrayInsertAt and ArrayDeleteAt functions. For more information on using the XmlChildPos function, see Determining the position of a child element with a common name, Adding an element, and Deleting elements.
XMLTransform(XMLVar,
XSLTStringVar)
Applies an Extensible Stylesheet Language Transformation (XSLT) to an XML document. The document can be represented either as a string variable or as an XML document object. The function returns the resulting XML document as a string.
For more information on using the XmlTransform function, see Transforming documents with XSLT.
XMLSearch(objectName,
"XPathExpression")
Uses an XPath expression to search an XML document object and returns an array of XML elements that match the search criteria.
For more information on using the XmlSearch. function, see Extracting data with XPath
IsXmlDoc(objectName)
Returns True if the function argument is an XML document object.
IsXmlElem(elementName)
Returns True if the function argument is an XML document object element.
IsXMLRoot(elementName)
Returns True if the function argument is the root element of an XML document object.
ToString(objectName)
Converts an XML document object to a string representation.

:

Note: The tags and functions that create XML document objects let you specify whether ColdFusion will treat the object in a case-sensitive manner. If you do not specify case-sensitivity, ColdFusion ignores the case of XML document object component identifiers, such as element and attribute names. If you do specify case-sensitivity, names with different cases refer to different components. For example, if you do not specify case-sensitivity, the names mydoc.employee.name[1] and mydoc.employee.NAME[1] always refer to the same element. If you specify case-sensitivity, these names refer to two separate elements.


Using an XML object

Because an XML document object is represented as a structure, you can access XML document contents using either, or a combination of both, of the following ways:

  • Using the element names, such as mydoc.employee.name[1]
  • Using the corresponding structure entry names (that is, XmlChildren array entries), such as mydoc.employee.XmlChildren[1]

Similarly, you can use either, or a combination of both, of the following notation methods:

  • Structure (dot) notation, such as mydoc.employee
  • Associative array (bracket) notation, such as mydoc["employee"]


Referencing the contents of an XML object

Use the following rules when you reference the contents of an XML document object on the right side of an assignment or as a function argument:

  • By default, ColdFusion ignores element name case. As a result, it considers the element name MyElement and the element name myELement to be equivalent. To make element name matching case-sensitive, specify CaseSensitive="True" in the cfxml tag, or specify True as a second argument in the XMLNew or XMLParse function that creates the document object.
  • Use an array index to specify one of multiple elements with the same name; for example, #mydoc.employee.name[1] and #mydoc.employee.name[2].

    • If you omit the array index on the last component of an element identifier, ColdFusion treats the reference as the array of all elements with the specified name. For example, mydoc.employee.name refers to an array of two name elements.

  • Use an array index into the XmlChildren array to specify an element without using its name; for example, mydoc.XmlRoot.XmlChildren[1].
  • Use associative array (bracket) notation to specify an element name that contains a period or colon; for example, myotherdoc.XmlRoot["Type1.Case1"].
  • You can use DOM methods in place of structure entry names.

For example, the following variables all refer to the XmlText value “Almanzo” in the XML document created in A simple XML document:

mydoc.XmlRoot.XmlChildren[1].XmlChildren[1].XmlText
mydoc.employee.name[1].first.XmlText
mydoc.employee.name[1]["first"].XmlText
mydoc["employee"].name[1]["first"].XmlText
mydoc.XmlRoot.name[1].XmlChildren[1]["XmlText"]

The following variables all refer to the EmpType attribute of the first name element in the XML document created in A simple XML document:

mydoc.employee.name[1].XmlAttributes.EmpType
mydoc.employee.name[1].XmlAttributes["EmpType"]
mydoc.employee.XmlChildren[1].EmpType
mydoc.XmlRoot.name[1].XmlAttributes["EmpType"]
mydoc.XmlRoot.XmlChildren[1].EmpType

Note that neither of these lists contains a complete set of the possible combinations that can make up a reference to the value or attribute.


Assigning data to an XML object

When you use an XML object reference on the left side of an expression, the preceding rules apply to the reference up to the last element in the reference string.

For example, the rules in “Referencing the contents of an XML object” apply to mydoc.employee.name[1].first in the following expression:

mydoc.employee.name[1].first.MyNewElement = XmlElemNew(mydoc, NewElement);

The following rules apply to the meaning of the last component on the left side of an expression:

  • The component name is an element structure key name (XML property name), such as XmlComment, ColdFusion sets the value of the specified element structure entry to the value of the right side of the expression. For example, the following line sets the XML comment in the mydoc.employee.name[1].first element to "This is a comment":
    • mydoc.employee.name[1].first.XmlComment = "This is a comment";
  • If the component name specifies an element name and does not end with a numeric index, for example mydoc.employee.name, ColdFusion assigns the value on the right of the expression to the first matching element.

    • For example, if both mydoc.employee.name[1] and mydoc.employee.name[2] exist, the following expression replaces mydoc.employee.name[1] with a new element named address, not an element named name:

    mydoc.employee.name = XmlElemNew(mydoc, "address");

After executing this line, if there had been both mydoc.employee.name[1] and mydoc.employee.name[2], there is now only one mydoc.employee.name element with the contents of the original mydoc.employee.name[2].
  • If the component name does not match an existing element, the element names on the left and right sides of the expression must match. ColdFusion creates a new element with the name of the element on the left of the expression. If the element names do not match, it generates an error.

    • For example if there is no mydoc.employee.name.phoneNumber element, the following expression creates a new mydoc.employee.name.phoneNumber element:

    mydoc.employee.name.phoneNumber = XmlElemNew(mydoc, "phoneNumber");

The following expression causes an error:

mydoc.employee.name.phoneNumber = XmlElemNew(mydoc, "address");
  • If the component name does not match an existing element and the component’s parent or parents also do not exist, ColdFusion creates any parent nodes as specified on the left side and use the previous rule for the last element. For example, if there is no mydoc.employee.phoneNumber element, the following expression creates a phoneNumber element containing an AreaCode element:
    • mydoc.employee.name.phoneNumber.AreaCode = XmlElemNew(mydoc, "AreaCode");


Creating and saving an XML document object

The following sections show the ways you can create and save an XML document object. The specific technique you use will depend on the application and your coding style.


Creating a new XML document object using the cfxml tag

The cfxml tag creates an XML document object that consists of the XML markup in the tag body. The tag body can include CFML code. ColdFusion processes the CFML code and includes the resulting output in the XML. The following example shows a simple cfxml tag:

<cfset testVar = True>
<cfxml variable="MyDoc">
   <MyDoc>
      <cfif testVar IS True>
         <cfoutput>The value of testVar is True.</cfoutput>
      <cfelse>
         <cfoutput>The value of testVar is False.</cfoutput>
      </cfif>
      <cfloop index = "LoopCount" from = "1" to = "4">
         <childNode>
            This is Child node <cfoutput>#LoopCount#.</cfoutput>
         </childNode>
      </cfloop>
   </MyDoc>
</cfxml>
<cfdump var=#MyDoc#>

This example creates a document object with a root element MyDoc, which includes text that displays the value of the ColdFusion variable testVar. MyDoc has four nested child elements, which are generated by an indexed cfloop tag. The cfdump tag displays the resulting XML document object.


Creating a new XML document object using the XmlNew function

The XmlNew function creates a new XML document object, which you must then populate. The following example creates and displays the same ColdFusion document object as in “Creating a new XML document object using the cfxml tag”:

<cfset testVar = True>
<cfscript>
   MyDoc = XmlNew();
   MyDoc.xmlRoot = XmlElemNew(MyDoc,"MyRoot");
   if (testVar IS TRUE)
      MyDoc.MyRoot.XmlText = "The value of testVar is True.";
   else
      MyDoc.MyRoot.XmlText = "The value of testVar is False.";
   for (i = 1; i LTE 4; i = i + 1)
      {
      MyDoc.MyRoot.XmlChildren[i] = XmlElemNew(MyDoc,"childNode");
      MyDoc.MyRoot.XmlChildren[i].XmlText = "This is Child node " & i &".";
      }
</cfscript>
<cfdump var=#MyDoc#>


Creating an XML document object from existing XML

The XmlParse function converts an XML document or document fragment represented as a text string into a ColdFusion document object.

If the XML document is already represented by a string variable, use the XmlParse tag directly on the variable. For example, if your application uses cfhttp action="get" to get the XML document, use the following line to create the XML document object:

<cfset myXMLDocument = XmlParse(cfhttp.fileContent)>

If the XML document is in a file, use cffile convert the file to a CFML variable, then use the XmlParse tag on the resulting variable. For example, if the XML document is in the file C:\temp\myxmldoc.xml, use the following code to convert the file to an XML document object:

<cffile action="read" file="C:\temp\myxmldoc.xml" variable="XMLFileText">
<cfset myXMLDocument=XmlParse(XMLFileText)>

Note: If the file is not encoded with the ASCII or Latin-1 character set, use the cffil tag charset attribute to specify the file’s character set. For example, if the file is encoded in UTF, specify charset="UTF-8".


Saving and exporting an XML document object

The ToString function converts an XML document object to a text string. You can then use the string variable in any ColdFusion tag or function.

To save the XML document in a file, use the ToString function to convert the document object to a string variable, then use the cffile tag to save the string as a file. For example, use the following code to save the XML document myXMLDocument in the file C:\temp\myxmldoc.xml:

<cfset XMLText=ToString(myXMLDocument)>
<cffile action="write" file="C:\temp\myxmldoc.xml" output="#XMLText#">


Modifying a ColdFusion XML object

As with all ColdFusion structured objects, you can often use a number of methods to change the contents of an XML document object. For example, you often have the choice of using an assignment statement or a function to update the contents of a structure or an array. The following section describes the array and structure functions that you can use to modify an XML document object. The section XML document object management reference provides a quick reference to modifying XML document object contents. Later sections describe these methods for changing document content in detail.


Functions for XML object management

The following table lists the ColdFusion array and structure functions that you can use to manage XML document objects and their functions, and describes their common uses. Note that in several cases you can use either an array function or a structure function for a purpose, such as for deleting all of an element’s attributes or children.

Function | Use
ArrayLen | Determines the number of child elements in an element, that is, the number of elements in an element’s XmlChildren array.
ArrayIsEmpty | Determines whether an element has any elements in its XmlChildren array.
StructCount | Determines the number of attributes in an element’s XmlAttributes structure.
StructIsEmpty | Determines whether an element has any attributes in its XmlAttributes structure. Returns True if the specified structure, including the XML document object or an element, exists and is empty.
StructKeyArray StructKeyList | Gets an array or list with the names of all of the attributes in an element’s XmlAttributes structure. Returns the names of the children of an XML element.
ArrayInsertAt | Adds a new element at a specific location in an element’s XmlChildren array.
ArrayAppend ArrayPrepend | Adds a new element at the end or beginning of an element’s XmlChildren array.
ArraySwap | Swaps the children in the XmlChildren array at the specified position.
ArraySet | Sets a range of entries in an XmlChildren array to equal the contents of a specified element structure. Each entry in the array range will be a copy of the structure. Can be used to set a single element by specifying the same index as the beginning and end of the range.
ArrayDeleteAt | Deletes a specific element from an element’s XmlChildren array.
ArrayClear | Deletes all child elements from an element’s XmlChildren array.
StructDelete | Deletes a selected attribute from an element’s XMLAttributes structure. Deletes all children with a specific element name from an element’s XmlChildren array. Deletes all attributes of an element. Deletes all children of an element. Deletes a selected property value.
StructClear | Deletes all attributes from an element’s XMLAttributes structure.
Duplicate | Copies an XML document object, element, or node structure.
IsArray | Returns True for the XmlChildren array. Returns false if you specify an element name, such as mydoc.XmlRoot.name, even if there are multiple name elements in XmlRoot.
IsStruct | Returns False for XML document objects, elements, and nodes. Returns True for XmlAttributes structures.
StructGet | Returns the specified structure, including XML document objects, elements, nodes, and XmlAttributes structures.
StructAppend | Appends a document fragment XML document object to another XML document object.
StructInsert | Adds a new entry to an XmlAttributes structure.
StructUpdate | Sets or replaces the value of a document object property such as XmlName, or of a specified attribute in an XmlAttributes structure.

Note: Array and structure functions not in the preceding or table or the table in the next section, do not work with XML document objects, XML elements, or XML node structures.


Treating elements with the same name as an array

In many cases an XML element has multiple children with the same name. For example, the example document used in this chapter has multiple name elements in the employee elements. In many cases, you can treat the child elements with identical names as an array. For example, to reference the second name element in mydoc.employee, you can specify mydoc.employee.name[2]. However, you can only use a limited set of Array functions when you use this notation. The following table lists the array functions that are valid for such references.

Array Function | Result
IsArray(elemPath.elemName) | Always returns False.
ArrayClear(elemPath.elemName) | Removes all the elements with name elemName from the elemPath element.
ArrayLen(elemPath.elemName) | Returns the number of elements named elemName in the elemPath element.
ArrayDeleteAt(elemPath.elemName, n) | Deletes the nth child named elemlName from the elemPath element.
IsEmpty(elemPath.elemName) | Always Returns False.
ArrayToList(elemPath.elemName, n) | Returns a comma separated list of all the XmlText properties of all the children of elemPath named elemName.


XML document object management reference

The following tables provide a quick reference to the ways you can modify the contents of an XML document object. The sections that follow describe in detail how to modify XML contents.


Adding

Use the following techniques to add new information to an element:

Type
Using a function
Using an assignment statement
Attribute
StructInsert(xmlElemPath.XmlAttributes,
   "key", "value")

xmlElemPath.XmlAttributes.key =
   "value"

xmlElemPath.XmlAttributes["key"]
   = "value"
Child element
To append:
ArrayAppend(xmlElempath.XmlChildren,
   newElem)
To insert:
ArrayInsertAt(xmlElempath.
   XmlChildren, position, newElem)
To append:
xmlElemPath.XmlChildren[i] =
   newElem

xmlElemPath.newChildName =
   newElem
(where newChildName must be the same as newElem.XmlName and cannot be an indexed name such as name[3])


Deleting

Use the following techniques to delete information from an element:

Type
Using a function
Using an assignment statement
Property
StructDelete(xmlElemPath, propertyName)

xmlElemPath.propertyName=""
Attribute
All attributes:
StructDelete(xmlElemPath, XmlAttributes)
A specific attribute
StructDelete(xmlElemPath.XmlAttributes,
"attributeName")
Not available
Child element
All children of an element:
StructDelete(xmlElemPath, "XmlChildren")
or
ArrayClear(xmlElemPath.XmlChildren)
All children with a specific name:
StructDelete(xmlElementpath,
   "elemName")
ArrayClear(xmlElemPath.elemName)
A specific child:
ArrayDeleteAt(xmlElemPath.XmlChildren,
   position)
ArrayDeleteAt(xmlElemPath.elemName,
   position)

Not available


Changing

Use the following techniques to change the contents of an element:

Type
Using a function
Using an assignment statement
Property
StructUpdate(xmlElemPath,
   "propertyName", "value")

xmlElemPath.propertyName =
   "value"

xmlElemPath["propertyName"] =
   "value"
Attribute
StructUpdate(xmlElemPath.XmlAttributes,
   "attributeName", "value")

xmlElemPath.XmlAttributes.
   attributeName="value"

xmlElemPath.XmlAttributes
   ["attributeName"] = "value"
Child element
(replace)
ArraySet(xmlElemPath.XmlChildren, index,
   index, newElement)
(use the same value for both index entries to change one element)
Replace first or only child named elementName:
parentElemPath.elementName =
   newElement

parentElemPath["elementName"]
   = newElement
Replace a specific child named elementName:
parentElemPath.elementName
   [index] = newElement
or
parentElemPath["elementName"]
   [index] = newElement


Adding, deleting, and modifying XML elements

The following sections describe the basic techniques for adding, deleting, and modifying XML elements. The example code uses the XML document described in A simple XML document


Counting and finding the position of child elements

Often, an XML element has several children with the same name. For example, in the XML document defined in the simple XML document, the employee root element has multiple name elements.

To manipulate such an object, you often need to know the number of children of the same name, and you might need to know the position in the XmlChildren array of a specific child name that is used for multiple children. The following sections describe how to get this information.


Counting child elements

The following user-defined function determines the number of child elements with a specific name in an element:

<cfscript>
function NodeCount (xmlElement, nodeName)
{
   nodesFound = 0;
   for ( i = 1; i LTE ArrayLen(xmlElement.XmlChildren); i = i+1)
   {
      if (xmlElement.XmlChildren[i].XmlName IS nodeName)
         nodesFound = nodesFound + 1;
   }
   return nodesFound;
}
</cfscript>

The following lines use this function to display the number of nodes named “name” in the mydoc.employee element:

<cfoutput>
Nodes Found: #NodeCount(mydoc.employee, "name")#
</cfoutput>


Determining the position of a child element with a common name

The XmlChildPos function determines the location in the XmlChildren array of a specific element with a common name. You use this index when you need to tell ColdFusion where to insert or delete child elements. For example, if there are several name elements in mydoc.employee, use the following code to locate name[2] in the XmlChildren array:

<cfset nameIndex = XmlChildPos(mydoc.employee, "name", 2)>


Adding an element

You can add an element by creating a new element or by using an existing element.

Use the XmlElemNew function to create a new, empty element. This function has the following form:

XmlElemNew(docObject, elementName)

where docObject is the name of the XML document object in which you are creating the element, and elementName is the name you are giving the new element.

Use an assignment statement with an existing element on the right side to create a new element using an existing element. See Copying an existing element for more information on adding elements using existing elements.


Adding an element using a function

You can use the ArrayInsertAt or ArrayAppend functions to add an element to an XML document object. For example, the following line adds a phoneNumber element after the last element for employee.name[2]:

<cfset ArrayAppend(mydoc.employee.name[2].XmlChildren, XmlElemNew(mydoc,
         "phoneNumber"))>

The following line adds a new department element as the first element in employee. The name elements become the second and third elements.

<cfset ArrayInsertAt(mydoc.employee.XmlChildren, 1, XmlElemNew(mydoc,
         "department"))>

You must use the format parentElement.XmlChildren to specify the array of elements to which you are adding the new element. For example, the following line causes an error:

<cfset ArrayInsertAt(mydoc.employee.name, 2, XmlElemNew(mydoc, "PhoneNumber")>

If you have multiple child elements with the same name, and you want to insert a new element in a specific position, use the XmlChildPos function to determine the location in the XmlChildren array where you want to insert the new element. For example, the following code determines the location of mydoc.employee.name[1] and inserts a new name element as the second name element:

<cfscript>
nameIndex = XmlChildPos(mydoc.employee, "name", 1);
ArrayInsertAt(mydoc.employee.XmlChildren, nameIndex + 1, XmlElemNew(mydoc,
               "name"));
</cfscript>


Adding an element using direct assignment

You can use direct assignment to append a new element to an array of elements. You cannot use direct assignment to insert an element into an array of elements.

When you use direct assignment, you can specify on the left side an index into the XmlChildren array greater than the last child in the array. For example, if there are two elements in mydoc.employee, you can specify any number greater than two, such as mydoc.employee.XmlChildren[6]. The element is always added as the last (in this case, third) child.

For example, the following line appends a name element to the end of the child elements of mydoc.employee:

<cfset mydoc.employee.XmlChildren[9] = XmlElemNew(mydoc, "name")>

If the parent element does not have any children with the same name as the new child, you can specify the name of the new node or the left side of the assignment. For example, the following line appends a phoneNumber element to the children of the first name element in mydoc.employee:

<cfset mydoc.employee.name[1].phoneNumber = XmlElemNew(mydoc, "phoneNumber")>

You cannot use the node name on the left to add an element with the same name as an existing element in the parent. For example, if mydoc.employee has two name nodes, the following line causes an error:

<cfset mydoc.employee.name[3] = XmlElemNew(mydoc, "name")>

However, the following line does work:

<cfset mydoc.employee.XmlChilren[3] = XmlElemNew(mydoc, "name")>


Copying an existing element

You can add a copy of an existing element elsewhere in the document. For example, if there is a mydoc.employee.name[1].phoneNumber element, but no mydoc.employee. name[2].phoneNumber, the following line creates a new mydoc.employee. name[2]. phoneNumber element with the same value as the original element. This assignment copies the original element. Unlike with standard ColdFusion structures, you get a true copy, not a reference to the original structure. You can change the copy without changing the original.

<cfset mydoc.employee.name[2].phoneNumber = mydoc.employee.name[1].phoneNumber>

When you copy an element, the new element must have the same name as the existing element. If you specify the new element by name on the left side of an assignment, the element name must be the same as the name on the right side. For Example, the following expression causes an error:

<cfset mydoc.employee.name[2].telephne = mydoc.employee.name[1].phoneNumber>


Deleting elements

There are many ways to delete individual or multiple elements.


Deleting individual elements

Use the ArrayDeleteAt function to delete a specific element from an XML document object. For example, the following line deletes the second child element in the mydoc.employee element:

<cfset ArrayDeleteAt(mydoc.employee.XmlChildren, 2)>

If an element has only one child element with a specific name, you can also use the StructDelete function to delete the child element. For example, the following line deletes the phoneNumber element named in the second employee.name element:

<cfset StructDelete(mydoc.employee.name[2], "phoneNumber")>

When there are multiple child elements of the same name, you must specify the element position, either among the elements of the same name, or among all child elements. Fore example, you can use the following line to delete the second name element in mydoc.employee:

<cfset ArrayDeleteAt(mydoc.employee.name, 2)>

You can also determine the position in the XmlChildren array of the element you want to delete and use that position. To do so, use the XmlChildPos function. For example, the following lines determine the location of mydoc.employee.name[2] and delete the element:

<cfset idx = XmlChildPos(mydoc.employee, "name", 2)>
<cfset ArrayDeleteAt(mydoc.employee.XmlChildren, idx)>


Deleting multiple elements

If an element has multiple children with the same name, use the StructDelete function or ArrayClear function with an element name to delete all of an element’s child elements with that name. For example, both of the following lines delete all name elements from the employee structure

<cfset StructDelete(mydoc.employee, "name")>
<cfset ArrayClear(mydoc.employee.name)>

Use the StructDelete or ArrayClear function with XmlChildren to delete all of an element’s child elements. For example, each of the following lines deletes all child elements of the mydoc.employee.name[2] element:

<cfset StructDelete(mydoc.employee.name[2], "XmlChildren")>
<cfset ArrayClear(mydoc.employee.name[2].XmlChildren)>


Adding, changing, and deleting element attributes

You modify an element’s attributes the same way you change the contents of any structure. For example, each of the following lines adds a Status attribute the second mydoc.employee.name element:

<cfset mydoc.employee.name[2].XmlAttributes.Status="Inactive">
<cfset StructInsert(mydoc.employee.name[2].XmlAttributes, "Status", "Inactive")>

To change an attribute, use a standard assignment statement; for example:

<cfset mydoc.employee.name[2].XmlAttributs.Status="Active">

To delete an attribute, use StructDelete; for example:

<cfset StructDelete(mydoc.employee.name[1].XmlAttributes, "Status")>


Changing element properties

To change an element’s properties, including its text and comment, use a standard assignment expression. For example, use the following line to add "in the MyCompany Documentation Department" to the mydoc.employee XML comment:

<cfset mydoc.employee.XmlComment = mydoc.employee.XmlComment & "in the
MyCompany Documentation Department">


Changing an element name

The XML DOM does not support changing an element name directly. To change the name of an element, you must create a new element with the new name, insert it into the XML document object before or after the original element, copy all the original element’s contents to the new element, and then delete the original element


Clearing an element property value

To clear an element property value, either assign the empty string to the property or use the StructDelete function. For example, each of the following lines clears the comment string from mydoc.employee:

<cfset mydoc.employee.XmlComment = "">
<cfset StructDelete(mydoc.employee, "XmlComment")>


Replacing or moving an element

To replace an element with a new element, use a standard replacement expression. For example, to replace the mydoc.employee.department element with a new element named organization, use either of the following lines:

<cfset mydoc.employee.department = XmlElemNew(mydoc, "Organization")>
<cfset mydoc.employee.XmlChildren[1] = XmlElemNew(mydoc, "Organization")>

To replace an element with a copy of an existing element, use the existing element on the right side of an expression. For example, the following line replaces the phoneNumber element for mydoc.employee.name[2] with the phoneNumber element from mydoc.employee.name[1]:

<cfset mydoc.employee.name[2].phoneNumber=mydoc.employee.name[1].phoneNumber>

This creates a true copy of the name[1].phoneNumber element as name[2].phoneNumber.

To move an element, you must assign it to its new location, then delete it from its old location. For example, the following lines move the phoneNumber element from mydoc.employee.name[1] to mydoc.employee.name[2]

<cfset mydoc.employee.name[2].phoneNumber=mydoc.employee.name[1].phoneNumber>
<cfset StructDelete(mydoc.employee.name[1], "phoneNumber")>


Using XML and ColdFusion queries

You can convert XML documents into ColdFusion query objects and manipulate them using queries of queries. This technique does not require the use of XPath and provides a method of searching XML documents and extracting data that is natural to ColdFusion programmers.


Converting XML to a ColdFusion query

The following example reads an XML document, converts it to a query object, and then performs a query of queries on the object to extract selected data:

<!--- Read the file and convert it to an XML document object --->
<cffile action="read" file="C:\Neo\wwwroot\myexamples\employees.xml"
variable="myxml">
<cfset mydoc = XmlParse(myxml)>

<!--- get an array of employees --->
<cfset emp = mydoc.employee.XmlChildren>
<cfset size = ArrayLen(emp)>

<cfoutput>
Number of employees = #size#
<br>
</cfoutput>
<br>
<!--- create a query object with the employee data --->
<cfset myquery = QueryNew("fname, lname") >
<cfset temp = QueryAddRow(myquery, #size#)>
<cfloop index="i" from = "1" to = #size#>
   <cfset temp = QuerySetCell(myquery, "fname",
      #mydoc.employee.name[i].first.XmlText#, #i#)>
   <cfset temp = QuerySetCell(myquery, "lname",
      #mydoc.employee.name[i].last.XmlText#, #i#)>
</cfloop>

<!--- Dump the query object --->
Contents of the myquery Query object: <br>
<cfdump var=#myquery#>
<br><br>

<!--- Select entries with the last name starting with A and dump the result --->
<cfquery name="ImqTest" dbType="query">
   SELECT lname, fname
   FROM myquery
   WHERE lname LIKE 'A%'
</cfquery>
<cfdump var=#imqtest#>


Converting a query object to XML

The following example shows how to convert a query object to XML. It uses cfquery to get a list of employees from the CompanyInfo database and saves the information as an XML document.

<!--- Query the database and get the names in the employee table --->
<cfquery name="myQuery" datasource="CompanyInfo">
  SELECT FirstName, LastName
   FROM employee
</cfquery>

<!--- Create an XML document object containing the data --->
<cfxml variable="mydoc">
   <employee>
      <cfoutput query="myQuery">
          <name>
            <first>#FirstName#</first>
            <last>#LastName#</last>
         </name>
      </cfoutput>
   </employee>
</cfxml>

<!--- dump the resulting XML document object --->
<cfdump var=#mydoc#>
<!--- Write the XML to a file --->
<cffile action="write" file="C:\inetpub\wwwroot\xml\employee.xml"
      output=#toString(mydoc)#>


Transforming documents with XSLT

The Extensible Stylesheet Language Transformation (XSLT) technology transforms an XML document into another format or representation. For example, one common use of XSLT is to convert XML documents into HTML for display in a browser. XSLT has many other uses, including converting XML data to another format, such as converting XML in a vocabulary used by an order entry application into a vocabulary used by an order fulfillment application.

XSLT transforms an XML document by applying an Extensible Stylesheet Language (XSL) stylesheet. (When stored in a file, XSL stylesheets typically have the suffix xsl.) ColdFusion provides the XmlTransform function to apply an XSL transformation to an XML document. The function takes an XML document in string format or as an XML document object, and an XSL stylesheet in string format, and returns the transformed document as a string.

The following code:

  1. Reads the simpletransform.xsl stylesheet file into a string variable.
  2. Uses the stylesheet to transform the mydoc XML document object.
  3. Saves the resulting transformed document in a second file.
<cffile action="read" file="C:\Neo\wwwroot\testdocs\simpletransform.xsl"
variable="xslDoc">
<cfset transformedXML = XmlTransform(mydoc, xslDoc)>
<cffile action="write" file="C:\Neo\wwwroot\testdocs\transformeddoc.xml"
output=transformedXML>

XSL and XSLT are specified by the World-Wide Web Consortium (W3C). For detailed information on XSL, XSLT, and XSL stylesheets, see the W3C website at http://www.w3.org/Style/XSL/. There are also several books on using XSL and XSLT.


Extracting data with XPath

XPath is a language for addressing parts of an XML document. Like XSL, XPath is a W3C specification. One of the major uses of XPath is in XSL transformations. However, XPath has more general uses. In particular, it can extract data from XML documents, such as complex data set representations. Thus, XPath is another data querying tool.

XPath uses a pattern called an XPath expression to specify the information to extract from an XML document. For example, the simple XPath expression /employee/name selects the name elements in the employee root element.

The the XmlPath function uses XPath expressions to extract data from XML document objects. The function takes an XML document object and an XPath expression in string format, and returns an array of XML document objects containing the elements that meet the expression criteria.

The following example extracts all the elements named last, which contain the employee’s last names, from the employeesimple.xml file, and displays the names.

<cffile action="read"
   file="C:\inetpub\wwwroot\examples\employeesimple.xml"
   variable="myxml">
<cfscript>
   myxmldoc = XmlParse(myxml);
   selectedElements = XmlSearch(myxmldoc, "/employee/name/last");
   for (i = 1; i LTE ArrayLen(selectedElements); i = i + 1)
      writeoutput(selectedElements[i].XmlText & "<br>");
</cfscript>

XPath is specified by the World-Wide Web Consortium. For detailed information on XPath, see the W3C website at http://www.w3.org/TR/xpath. Most books that cover XSLT also discuss XPath.


Example: using XML in a ColdFusion application

The example in this section shows how you can use XML to represent data, and how ColdFusion can use XML data in an application. Although the example is too simple to be used in an application without substantial changes, it presents some of the common uses of XML with ColdFusion.

The example receives an order in the form of an XML document, processes it, and generates an XML receipt document. In this case, the order document is in a file, but it could be received as the result of an HTTP request, or retrieved using cfpop, cfftp, or other methods. The ColdFusion page does the following with the order:

  1. Generates a query object from an XML document.
  2. Queries a database table to determine the order discount percentage to use.
  3. Uses a query of queries to calculate the total price, then calculates the discounted price.
  4. Generates the receipt as an XML document.

This example displays the results of the processing steps to show you what has been done.


The XML document

The order.xml document has the following structure:

  • The root element is named order and has one attribute, id.
  • There is one customer element with firstname, lastname, and accountnum attributes. The customer element does not have a body
  • There is one items element that contains multiple item elements
  • Each item element has an id attribute and contains a name, quantity, and unitprice element. The name, quantity, and unitprice elements contain their value as body text.

The following order.xml document works correctly with the information in the CompanyInfo database:

<order id="4323251">
   <customer firstname="Philip" lastname="Cramer" accountNum="21"/>
   <items>
      <item id="43">
         <name>
            Large Hammer
         </name>
         <quantity>
            1
         </quantity>
         <unitprice>
            15.95
         </unitprice>
      </item>
      <item id="54">
         <name>
            Ladder
         </name>
         <quantity>
            2
         </quantity>
         <unitprice>
            40.95
         </unitprice>
      </item>
      <item id="68">
         <name>
            Paint
         </name>
         <quantity>
            10
         </quantity>
         <unitprice>
            18.95
         </unitprice>
      </item>
   </items>
</order>


The ColdFusion page

The ColdFusion page looks like the following:

<!--- Convert file to XML document object --->
<cffile action="read" file="C:\Neo\wwwroot\examples\order.xml" variable="myxml">
<cfset mydoc = XmlParse(myxml)>

<!--- Extract account number --->
 <cfset accountNum=#mydoc.order.customer.XmlAttributes.accountNum#>
<!--- Display Order Information --->
<cfoutput>
   <b>Name=</b>#mydoc.order.customer.XmlAttributes.firstname#
        #mydoc.order.customer.XmlAttributes.lastname#
   <br>
   <b>Account=</b>#accountNum#
   <br>
   <cfset numItems = ArrayLen(mydoc.order.items.XmlChildren)>
   <b>Number of items ordered=</b> #numItems#
</cfoutput>
<br><br>

<!--- Process the order into a query object --->
<cfset orderquery = QueryNew("item_Id, name, qty, unitPrice") >
<cfset temp = QueryAddRow(orderquery, #numItems#)>
<cfloop index="i" from = "1" to = #numItems#>
   <cfset temp = QuerySetCell(orderquery, "item_Id",
      #mydoc.order.items.item[i].XmlAttributes.id# ,#i#)>
   <cfset temp = QuerySetCell(orderquery, "name",
      #mydoc.order.items.item[i].name.XmlText#, #i#)>
   <cfset temp = QuerySetCell(orderquery, "qty",
      #mydoc.order.items.item[i].quantity.XmlText# ,#i#)>
   <cfset temp = QuerySetCell(orderquery, "unitPrice",
      #mydoc.order.items.item[i].unitprice.XmlText#, #i#)>
</cfloop>

<!--- Display the order query --->
<cfdump var=#orderquery#>
<br><br>

<!--- Determine the discount --->
<cfquery name="discountQuery" datasource="CompanyInfo">
   SELECT *
   FROM employee
   WHERE Emp_Id = #accountNum#
</cfquery>
<cfset drate = 0>
<cfif #discountQuery.RecordCount# is 1>
   <cfset drate = 10>
</cfif>

<!--- Display the discount rate --->
<cfoutput>
   <b>Discount Rate =</b> #drate#%
</cfoutput>
<br><br>

<!--- Compute the total cost and discount price--->
<cfquery name="priceQuery" dbType="query">
   SELECT SUM(qty*unitPrice)
   AS totalPrice
   FROM orderquery
</cfquery>
<cfset discountPrice = priceQuery.totalPrice * (1 - drate/100)>

<!--- Display the full price and discounted price --->
<cfoutput>
   <b>Full Price=</b> #priceQuery.totalPrice#<br>
   <b>Discount Price=</b> #discountPrice#
</cfoutput>
<br><br>

<!---Generate an XML Receipt --->
<cfxml variable="receiptxml">
<receipt num = "34">
<cfoutput>
   <price>#discountPrice#</price>
   <cfif drate GT 0 >
     <discountRate>#drate#</discountRate>
   </cfif>
</cfoutput>
  <itemsFilled>
     <cfoutput query="orderQuery">
      <name>   #name# </name>
      <qty>   #qty#  </qty>
      <price>  #qty*unitPrice#  </price>
     </cfoutput>
  </itemsFilled>
</receipt>
</cfxml>

<!--- Display the resulting receipt --->
<cfdump var=#receiptxml#>


Reviewing the code

The following table describes the CFML code and its function. For the sake of brevity it does not include code that displays the processing results

Code
Description
<cffile action="read"
   file="C:\Neo\wwwroot\examples\order.xml"
   variable="myxml">
<cfset mydoc = XmlParse(myxml)>
<cfset accountNum=#mydoc.order.
   customer.XmlAttributes.accountNum#>
Reads the XML from a file and convert it to an XML document object.
Sets the accountNum variable from the customer entry’s accountnum attribute.
<cfset orderquery = QueryNew("item_Id,
   name, qty, unitPrice") >
<cfset temp = QueryAddRow(orderquery,
   #numItems#)>
<cfloop index="i" from = "1" to = #numItems#>
  <cfset temp = QuerySetCell(orderquery,
    "item_Id", #mydoc.order.items.item[i].
    XmlAttributes.id# ,#i#)>
  <cfset temp = QuerySetCell(orderquery,
    "name", #mydoc.order.items.item[i].
    name.XmlText#, #i#)>
  <cfset temp = QuerySetCell(orderquery,
    "qty", #mydoc.order.items.item[i].
    quantity.XmlText# ,#i#)>
  <cfset temp = QuerySetCell(orderquery,
    "unitPrice", #mydoc.order.items.item[i].
    unitprice.XmlText#, #i#)>
</cfloop>
Converts the XML document object into a query object.
Creates a query with columns for the item_id, name, qty, and unitPrice values for each item.
For each XML item entry in the mydoc.order.items entry, fills one row of the query with the item’s id attribute and the text in the name, quantity, and unitprice entries that the it contains.
<cfquery name="discountQuery"
     datasource="CompanyInfo">
   SELECT *
   FROM employee
   WHERE Emp_Id = #accountNum#
</cfquery>
<cfset drate = 0>
<cfif #discountQuery.RecordCount# is 1>
   <cfset drate = 10>
</cfif>
If the account number is the same as an employee ID in the CompanyInfo database Employee table, the query returns one record. and RecordCount equals 1. In this case, sets a discount rate of 10%. Otherwise, sets a discount rate of 0%.
<cfquery name="priceQuery" dbType="query">
   SELECT SUM(qty*unitPrice)
   AS totalPrice
   FROM orderquery
</cfquery>
<cfset discountPrice = priceQuery.totalPrice
   * (1 - drate/100)>
Uses a query of queries with the SUM operator to calculate the total cost before discount of the ordered items, then applies the discount to the price. Note that the result of the query is a single value, the total price.
<cfxml variable="receiptxml">
 <receipt num = "34">
  <cfoutput>
   <price>#discountPrice#</price>
   <cfif drate GT 0 >
    <discountRate>#drate#</discountRate>
    </cfif>
  </cfoutput>
  <itemsFilled>
   <cfoutput query="orderQuery">
    <name>   #name# </name>
    <qty>   #qty#  </qty>
    <price>  #qty*unitPrice#  </price>
   </cfoutput>
  </itemsFilled>
 </receipt>
</cfxml>
Creates an XML document object as a receipt. The receipt has a root element named receipt, which has the receipt number as an attribute. The receipt element contains a price element with the order cost and an itemsFilled element with one item element for each item.


Moving complex data across the web with WDDX

WDDX is an XML vocabulary for describing a complex data structure, such as an array, associative array (such as a ColdFusion structure), or a recordset, in a generic fashion. It lets you use HTTP to move the data between different application server platforms and between application servers and browsers. Target platforms for WDDX include ColdFusion, Active Server Pages (ASP), JavaScript, Perl, Java, Python, COM, Macromedia Flash, and PHP.

The WDDX XML vocabulary consists of a document type definition (DTD) that describes the structure of standard data types and a set of components for each of the target platforms to do the following:

  • Serialize the data from its native representation into a WDDX XML document or document fragment
  • Deserialize a WDDX XML document or document fragment into the native data representation, such as a CFML structure

This vocabulary creates a way to move data, its associated data types, and descriptors that allow the data to be manipulated on a target system, between arbitrary application servers.

Note: The WDDX DTD, which includes documentation, is located at http://www.openwddx.org/downloads/dtd/wddx_dtd_10.txt.

While WDDX is a valuable tool for ColdFusion developers, its usefulness is not limited to CFML. If you serialize a common programming data structure (such as an array, recordset, or structure) into WDDX format, you can use HTTP to transfer the data across a range of languages and platforms. Also, you can use WDDX to store complex data in a database, file, or even a Client variable.

WDDX has two features that make it useful for transferring data in a web environment:

  • It is lightweight. The JavaScript used to serialize and deserialze data, including a debugging function to dump WDDX data, occupies less than 22KB.
  • Unlike traditional client-server approaches, the source and target system can have minimal-to-no prior knowledge of each other. They only need to know the structure of the data that is being transferred.

WDDX was created in 1998, and many applications now expose WDDX capabilities. The best source of information about WDDX is http://www.openwddx.org. This site offers free downloads of the WDDX DTD and SDK and a number of resources, including a WDDX FAQ, a developer forum, and links to additional sites that provide WDDX resources.


Uses of WDDX

WDDX is useful for transferring complex data between applications. For example, you can use it to exchange data between a CFML application and a CGI or PHP application. WDDX is also useful for transferring data between the server and client-side JavaScript.


Exchanging data across application servers

WDDX is useful for the transfer of complex, structured data seamlessly between different application server platforms. For example, an application based on ColdFusion at one business could use cfwddx to convert a purchase order structure to WDDX. It could then use cfhttp to send the WDDX to a supplier running a CGI-based system.

The supplier could then deserialize the WDDX to its native data form, the extract information from the order, and pass it to a shipping company running an application based on ASP.


Transferring data between the server and browser

You can use WDDX for server-to-browser and browser-to-server data exchanges. You can transfer server data to the browser in WDDX format and convert it to JavaScript objects on the browser. Similarly, your application pages can serialize JavaScript data generated on the browser into WDDX format and transfer the data to the application server. You then deserialize the WDDX XML into CFML data on the server.

On the server you use the cfwddx tag to serialize and deserialize WDDX data. On the browser, you use WddxSerializer and WddxRecordset JavaScript utility classes to serialize the JavaScript data to WDDX. (ColdFusion installs these utility classes on your server as webroot/CFIDE/scripts/wddx.js.)


WDDX and web services

WDDX does not compete with web services. It is a complementary technology focused on solving simple problems of application integration by sharing data on the web in a pragmatic, productive manner at very low cost.

WDDX offers the following advantages:

  • It can be used by lightweight clients, such as browsers or the Macromedia Flash player.
  • It can be used to store complex data structures in files and databases.

Applications that take advantage of WDDX can continue to do so if they start to use web services. These applications could also be converted to use web services standards exclusively; only the service and data interchange formats--not the application model--must change.


How WDDX works

The following example shows how WDDX works. A simple structure with two string variables might have the following form after it is serialized into a WDDX XML representation:

<var name='x'>
   <struct>

      <var name='a'>
         <string>Property a</string>
      </var>
      <var name='b'>
         <string>Property b</string>
      </var>
   </struct>
</var>

When you deserialize this XML into CFML or JavaScript, the result is a structure that is created by either of the following scripts:

JavaScript
CFScript
x = new Object();
x.a = "Property a";
x.b = "Property b";

x = structNew();
x.a = "Property a";
x.b = "Property b";

Conversely, when you serialize the variable x produced by either of these scripts into WDDX, you generate the XML listed above.

ColdFusion provides a tag and JavaScript objects that convert between CFML, WDDX, and JavaScript. Serializers and deserializers for other data formats are available on the web. For more information, see http://www.openwddx.org

Note: The cfwddx tag and the wddx.js JavaScript functions use UTF-8 encoding to represent data. Any tools that deserialize ColdFusion-generated WDDX must accept UTF-8 encoded characters. UTF-8 encoding is identical to the ASCII and ISO 8859 single-byte encodings for the standard 128 "7-bit" ASCII characters. However, UTF-8 uses a two-byte representation for "high-ASCII" ISO 8859 characters where the initial bit is 1.


WDDX data type support

The following sections describe the data types that WDDX supports. This information is a distillation of the description in the WDDX DTD. For more detailed information, see the DTD at http://www.openwddx.org.


Basic data types

WDDX can represent the following basic data types:

Data type | Description
Null | Null values in WDDX are not associated with a type such as number or string. The cfwddx tag converts WDDX Nulls to empty strings.
Numbers | WDDX documents use floating point numbers to represent all numbers. The range of numbers is restricted to +/-1.7E+/-308. The precision is restricted to 15 digits after the decimal point.
Date-time values | Date-time values are encoded according to the full form of ISO8601; for example, 2002-9-15T09:05:32+4:0.
Strings | Strings can be of arbitrary length and must not contain embedded nulls. Strings can be encoded using double-byte characters.


Complex data types

WDDX can represent the following complex data types:

Data type | Description
Array | Arrays are integer-indexed collections of objects of arbitrary type. Because most languages start array indexes at 0, while CFML array indexes start at 1, working with array indices can lead to nonportable data.
Structure | Structures are string-indexed collections of objects of arbitrary type, sometimes called associative arrays. Because some of the languages supported by WDDX are not case-sensitive, no two variable names in a structure can differ only in their case.
Recordset | Recordsets are tabular rows of named fields, corresponding to ColdFusion query objects. Only simple data types can be stored in recordsets. Because some of the languages supported by WDDX are not case-sensitive, no two field names in a recordset can differ only in their case. Field names must satisfy the regular expression [_A-Za-z][_.0-9A-Za-z]* where the period (.) stands for a literal period character, not “any character”.
Binary | The binary data type represents strings (blobs) of binary data. The data is encoded in MIME base64 format.


Data type comparisons

The following table compares the basic WDDX data types with the data types to which they correspond in the languages and technologies commonly used on the web:

WDDX | CFML | XML Schema | Java | ECMAScript/ JavaScript | COM
null | N/A | N/A | null | null | VT_NULL
boolean | Boolean | boolean | java.lang.Boolean | boolean | VT_BOOL
number | Number | number | java.lang.Double | number | VT_R8
dateTime | DateTime | dateTime | java.lang.Date | Date | VT_DATE
string | String | string | java.lang.String | string | VT_BSTR
array | Array | N/A | java.lang.Vector | Array | VT_ARRAY | VT_VARIANT
struct | Structure | N/A | java.lang. Hashtable | Object | IWDDXStruct
recordset | Query object | N/A | coldfusion.run time.QueryTable | WddxRecordset | IWDDXRecordset
binary | Binary | binary | byte[] | WddxBinary | V_ARRAY | UI1


Time zone processing

Producers and consumers of WDDX packets can be in geographically dispersed locations. Therefore, it is important to use time zone information when serializing and deserializing data, to ensure that date-time values are represented correctly.

The cfwddx action=cfml2wddx tag useTimezoneInfo attribute specifies whether to use time zone information in serializing the date-time data. In the JavaScript implementation, useTimezoneInfo is a property of the WddxSerializer object. In both cases the default useTimezoneInfo value is True.

Date-time values in WDDX are represented using a subset of the ISO8601 format. Time zone information is represented as an hour/minute offset from Coordinated Universal Time (UTC); for example, “2002-9-8T12:6:26-4:0”.

When the cfwddx tag deserializes WDDX to CFML, it automatically uses available time zone information, and converts date-time values to local time. In this way, you do not need to worry about the details of time zone conversions.

However, when the JavaScript objects supplied with ColdFusion deserialize WDDX to JavaScript expressions, they do not use time zone information, because in JavaScript it is difficult to determine the time zone of the browser.


Using WDDX

The following sections describe how you can use WDDX in ColdFusion applications. The first two sections describe the tools that ColdFusion provides for creating and converting WDDX. The remaining sections show how you use these tools for common application uses.


Using the cfwddx tag

The cfwddx tag can do the following conversions:

From | To
CFML | WDDX
CFML | JavaScript
WDDX | CFML
WDDX | JavaScript

A typical cfwddx tag used to convert a CFML query object to WDDX looks like the following:

<cfwddx action="cfml2wddx" input="#MyQueryObject#" output="WddxTextVariable">

In this example, MyQueryObject is the name of the query object variable, and WddxTextVariable is the name of the variable in which to store the resulting WDDX XML. Note

For more information on the cfwddx tag see the CFML Reference.


Validating WDDX data

The cfwddx tag has a Validate attribute that you can use when converting WDDX to CFML or JavaScript. When you set this attribute to True, the XML parser uses the WDDX DTD to validate the WDDX data before deserializing it. If the WDDX is not valid, ColdFusion generates an error. By default, ColdFusion does not validate WDDX data before trying to convert it to ColdFusion or JavaScript data.

The IsWddx function returns True if a variable is a valid WDDX data packet. It returns False otherwise. You can use this function to validate WDDX packets before converting them to another format. For example, you can use it instead of the cfwddx validate attribute, so that invalid WDDX is handled within conditional logic instead of error-handling code. You can also use it to pre-validate data that will be deserialized by JavaScript at the browser.


Using JavaScript objects

ColdFusion provides two JavaScript objects, WddxSerializer and WddxRecordset, that you can use in JavaScript to convert data to WDDX. These objects are defined in the file webroot/cfide/scripts/wddx.js.

The CFML Reference describes these objects and their methods in detail. The example Transferring data from the browser to the server shows how you can use these objects to serialize JavaScript to WDDX.


Converting CFML data to a JavaScript object

The following example demonstrates the transfer of a cfquery recordset from a CFML page executing on the server to a JavaScript object that is processed by the browser.

The application consists of four principal sections:

  • Running a data query
  • Including the WDDX JavaScript utility classes
  • Calling the conversion function
  • Writing the object data in HTML

The example uses the cfsnippets data source that is installed with ColdFusion.

<!--- Create a simple query  --->
<cfquery name = "q" datasource ="cfsnippets">
   SELECT Message_Id, Thread_id, Username, Posted
   FROM messages
</cfquery>

<!--- Load the wddx.js file, which includes the dump function --->
<script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script>

<script>
   // Use WDDX to move from CFML data to JavaScript
   <cfwddx action="cfml2js" input="#q#" topLevelVariable="qj">

   // Dump the recordset to show that all the data has reached
   // the client successfully.
   document.write(qj.dump(true));
</script>

Note: To see how cfwddx Action="cfml2js" works, save this code under your webroot directory, for example in wwwroot/myapps/wddxjavascript.cfm, run the page in your browser and select View Source in your browser.


Transferring data from the browser to the server

The following example serializes form field data, posts it to the server, deserializes it, and displays the data. For simplicity, it only collects a small amount of data. In applications that generate complex JavaScript data collections, you can extend this basic approach very effectively. Note that this example uses the WddxSerializer JavaScript object to serialize the data, and the cfwddx tag to deserialize the data.

To use the example:

  1. Save the file under your webroot directory, for example in wwwroot/myapps/ wddxserializedeserialze.cfm
  2. Display http://localhost/myapps/wddxserializedeserialze.cfm in your browser.
  3. Enter a first name and last name in the form fields.
  4. Click Next.

    5. The name appears in the Names added so far box.

  5. Repeat steps 3 and 4 to add as many names as you wish.
  6. Click Serialize to serialize the resulting data.

    7. The resulting WDDX packet appears in the WDDX packet display box. This step is intended only for test purposes. Real applications handle the serialization automatically.

  7. Click Submit to submit the data.

    8. The WDDX packet is transferred to the server-side processing code, which deserializes it and displays the information.

<!--- load the wddx.js file --->
<script type="text/javascript" src="/CFIDE/scripts/wddx.js"></script>

<!--- Data binding code --->
<script>

   // Generic serialization to a form field
   function serializeData(data, formField)
   {
      wddxSerializer = new WddxSerializer();
      wddxPacket = wddxSerializer.serialize(data);
      if (wddxPacket != null)
      {
         formField.value = wddxPacket;
      }
      else
      {
         alert("Couldn't serialize data");
      }
   }

   // Person info recordset with columns firstName and lastName
   // Make sure the case of field names is preserved
   var personInfo = new WddxRecordset(new Array("firstName",
   "lastName"), true);

   // Add next record to end of personInfo recordset
   function doNext()
   {
      // Extract data
      var firstName = document.personForm.firstName.value;
      var lastName = document.personForm.lastName.value;

      // Add names to recordset
      nRows = personInfo.getRowCount();
      personInfo.firstName[nRows] = firstName;
      personInfo.lastName[nRows] = lastName;

      // Clear input fields
      document.personForm.firstName.value = "";
      document.personForm.lastName.value = "";

      // Show added names on list
      // This gets a little tricky because of browser differences
      var newName = firstName + " " + lastName;
      if (navigator.appVersion.indexOf("MSIE") == -1)
      {
         document.personForm.names[length] =
           new Option(newName, "", false, false);
      }
      else
      {
         // IE version
         var entry = document.createElement("OPTION");
         entry.text = newName;
         document.personForm.names.add(entry);
      }

   }

</script>

<!--- Data collection form --->
<form action="#cgi.script_name#" method="Post"
name="personForm">

   <!--- Input fields --->
   Personal information<br>
   First name: <input type=text name=firstName><br>
   Last name: <input type=text name=lastName><br>
   <br>

   <!--- Navigation & submission bar --->
   <input type="button" value="Next" onclick="doNext()">
   <input type="button" value="Serialize"
   onclick="serializeData(personInfo, document.personForm.wddxPacket)">
   <input type="submit" value="Submit">
   <br><br>
   Names added so far:<br>
   <select name="names" size="5">
   </select>
   <br>

   <!--- This is where the WDDX packet will be stored --->
   <!--- In a real application this would be a hidden input field. --->
   <br>
   WDDX packet display:<br>
   <textarea name="wddxPacket" rows="10" cols="80" wrap="Virtual">
   </textarea>

</form>

<!--- Server-side processing --->
<hr>
<b>Server-side processing</b><br>
<br>
<cfif isdefined("form.wddxPacket")>
   <cfif form.wddxPacket neq "">

      <!--- Deserialize the WDDX data --->
      <cfwddx action="wddx2cfml" input=#form.wddxPacket#
      output="personInfo">

      <!--- Display the query --->
      The submitted personal information is:<br>
      <cfoutput query=personInfo>
         Person #CurrentRow#: #firstName# #lastName#<br>
      </cfoutput>
   <cfelse>
      The client did not send a well-formed WDDX data packet!

   </cfif>
<cfelse>
   No WDDX data to process at this time.
</cfif>


Storing complex data in a string

The following simple example uses WDDX to store complex data, a data structure that contains arrays as a string in a Client variable. It uses the cfdump tag to display the contents of the structure before serialization and after deserialization. It uses the HTMLEditFormat function in a cfoutput tag to display the contents of the Client variable. The HTMLEditFormat function is required to prevent the browser from trying to interpret (and throwing away) the XML tags in the variable.

<!--- Enable client state management --->
<cfapplication name="relatives" clientmanagement="Yes">

<!--- Build a complex data structure --->
<cfscript>
   relatives = structNew();
   relatives.father = "Bob";
   relatives.mother = "Mary";
   relatives.sisters = arrayNew(1);
   arrayAppend(relatives.sisters, "Joan");
   relatives.brothers = arrayNew(1);
   arrayAppend(relatives.brothers, "Tom");
   arrayAppend(relatives.brothers, "Jesse");
</cfscript>

A dump of the original relatives structure:<br>
<br>
<cfdump var="#relatives#"><br>
<br>

<!--- Convert data structure to string form and save it in the
         client scope --->
<cfwddx action="cfml2wddx" input="#relatives#" output="Client.wddxRelatives">

The contents of the Client.wddxRelatives variable:<br>
<cfoutput>#HtmlEditFormat(Client.wddxRelatives)#</cfoutput><br>
<br>

<!--- Now read the data from client scope into a new structure --->
<cfwddx action="wddx2cfml" input="#Client.wddxRelatives#" output="sameRelatives">

A dump of the sameRelatives structure <br>
generated from client.wddxRelatives<br>
<br>
<cfdump var="#sameRelatives#">

Previous


Using Web Services

Web services let you publish and consume remote application functionality over the Internet. When you consume web services, you access remote functionality to perform an application task. When you publish a web service, you let remote users access your application functionality to build it into their own applications.

This chapter describes how to consume and publish web services.

Contents
  • Web services
  • Working with WSDL files
  • Consuming web services
  • Publishing web services
  • Handling complex data types
Next


Web services

Since its inception, the Internet has allowed people to access content stored on remote computers. This content can be static, such as a document represented by an HTML file, or dynamic, such as content returned from a ColdFusion page or CGI script.

Web services are a new technology that lets you access application functionality, which resides on remote computers, that someone created and made available. With a web service, you can make a request to the remote application to perform an action.

For example, you can request a stock quote, pass a text string to be translated, or request information from a product catalog. The advantage of web services is that you do not have to recreate application logic that someone else has already created and, therefore, you can build your applications faster.

Referencing a remote web service within your ColdFusion application is called consuming web services. Since web services adhere to a standard interface regardless of implementation technology, you can consume a web service implemented as part of a ColdFusion application, or as part of a .NET or Java application.

You can also create your own web services and make them available to others for remote access, called publishing web service. Applications that consume your web service can be implemented in ColdFusion or by any application that recognizes the web service standard.


Accessing a web service

In its simplest form, an access to a web service is similar to a function call. Instead of the function call referencing a library on your computer, it references remote functionality over the Internet.

One feature of web services is that they are self describing. That means a person who makes a web service available also publishes a description of the API to the web service as a Web Services Description Language (WSDL) file.

A WSDL file is an XML-formatted document that includes information about the web service, including the following information:

  • Operations that you can call on the web service
  • Input parameters that you pass to each operation
  • Return values from an operation

Consuming web services typically is a two-step process:

  1. Parse the WSDL file of the web service to determine its interface.

    2. A web service makes its associated WSDL file available over the Internet. You need to know the URL of the WSDL file defining the service. For example, you can access the WSDL file for the BabelFish web service at the following URL:

    wsdlhttp://www.xmethods.net/sd/2001/BabelFishService.wsdl

    The section Working with WSDL files contains an overview of WSDL syntax.

  2. Make a request to the web service.

    3. The following example invokes an operation on the BabelFish web service to translate the string "Hello World" from English into Spanish:

    <cfinvoke
   webservice='http://www.xmethods.net/sd/2001/BabelFishService.wsdl'
   method='BabelFish'
   translationmode="en_es"
   sourcedata="Hello World"
   returnVariable='foo'>
<cfoutput>#foo#</cfoutput>

For more information on consuming web services, see Consuming web services.


Basic web service concepts

You must be familiar with the underlying architecture of a web service provider in order to fully understand how web services work.

Note: This section contains an overview of the architecture of web services. For detailed information, consult one of the many web services books.

The following are three primary components of the web services platform:

  • SOAP (Simple Access Open Protocol)
  • WSDL
  • UDDI (Universal Description, Discovery, and Integration)

The following simple figure shows how the ColdFusion implementation of web services work:

This is a picture of the feature being described.

The following sections describe the components shown in this figure.


Supporting web services with SOAP

SOAP provides a standard XML structure for sending and receiving web service requests and responses over the Internet. Usually you send SOAP messages using HTTP, but you also can send them using SMTP and other protocols. ColdFusion integrates the Apache Axis SOAP engine to support web services.

The ColdFusion Web Services Engine performs the underlying functionality to support web services, including generating WSDL files for web services that you create. In ColdFusion, to consume or publish web services does not require you to be familiar with SOAP or to perform any SOAP operations.

You can find additional information about SOAP in the W3C’s SOAP 1.1 note at the following URL:


Describing web services with WSDL

A WSDL document is an XML file that describes a web service’s purpose, where it is located, and how to access it. The WSDL document describes the operations that you can invoke and their associated data types.

ColdFusion can generate a WSDL document from a web service, and you can publish the WSDL document at a URL to provide information to potential clients. For more information, see Working with WSDL files.


Finding web services with UDDI

As a consumer of web services, you want to know what web services are available. As a publisher of web services, you want others to be able to find information about your web services. Universal Description, Discovery and Integration (UDDI) provides a way for web service clients to dynamically locate web services that provide specific capabilities. You use a UDDI query to find service providers. A UDDI response contains information, such as business contact information, business category, and technical details, about how to invoke a web service.

Although ColdFusion does not directly support UDDI, you can manually register or find a web service using a public UDDI registry, such as the IBM UDDI Business Registry at the following URL:

You can find additional information about UDDI at the following URL:


Working with WSDL files

WSDL files define the interface to a web service. To consume a web service, you access the service’s WSDL file to determine information about it. If you publish your application logic as a web service, you must create a WSDL file for it.

WSDL is a draft standard supported by the World Wide Web Consortium. You can access the specification at the following URL:

http://www.w3.org/TR/wsdl


Creating a WSDL file

To publish a web service, you construct the service’s functionality and then create the WSDL file defining the service. In ColdFusion, you use components to create web services. ColdFusion automatically generates the WSDL file for a component that you use to produce a web service. For more information on creating web services, see Publishing web services.

For more information on components, see Building and Using ColdFusion Components.


Viewing a WSDL file using Dreamweaver MX

Dreamweaver MX contains a utility to view web services, including operation names, parameter names, and parameter data types. The following figure shows a WSDL file for the BabelFish web service.

This is a picture of the feature being described.

This figure shows that the web service method babelFish returns a string, and that it takes string parameters named sourcedata and translationmode as input.

To open the Components tab in the Dreamweaver MX and add a web service, use the following procedure:

  1. Choose Window > Components, or use Ctrl-F7, to open the Components panel.
  2. In the Components panel, choose Web Services from the dropdown list in the upper-left of the panel.
  3. Click the Plus (+) button.

    4. The Add Using WSDL dialog box appears.

  4. Specify the URL of the WSDL file you want to use.

For more information on using Dreamweaver MX, see its online help system.


Reading a WSDL file

A WSDL file takes practice to read. You can view the WSDL file in a browser, or you can use a tool such as Dreamweaver MX, which contains a built-in utility for displaying WSDL files in an easy-to-read format.

The following example shows a WSDL file for the BabelFish web service:

<?xml version="1.0" ?>
   <definitions name="BabelFishService"
xmlns:tns="http://www.xmethods.net/sd/BabelFishService.wsdl"
targetNamespace="http://www.xmethods.net/sd/BabelFishService.wsdl"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
      <message name="BabelFishRequest">
         <part name="translationmode" type="xsd:string" />
         <part name="sourcedata" type="xsd:string" />
      </message>
      <message name="BabelFishResponse">
         <part name="return" type="xsd:string" />
      </message>
      <portType name="BabelFishPortType">
         <operation name="BabelFish">
            <input message="tns:BabelFishRequest" />
            <output message="tns:BabelFishResponse" />
         </operation>
      </portType>
      <binding name="BabelFishBinding" type="tns:BabelFishPortType">
         <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"
/>
         <operation name="BabelFish">
            <soap:operation soapAction="urn:xmethodsBabelFish#BabelFish" />
            <input>
               <soap:body use="encoded" namespace="urn:xmethodsBabelFish"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </input>
            <output>
               <soap:body use="encoded" namespace="urn:xmethodsBabelFish"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
            </output>
         </operation>
      </binding>
   <service name="BabelFishService">
      <documentation>Translates text of up to 5k in length, between a variety of
languages.</documentation>
      <port name="BabelFishPort" binding="tns:BabelFishBinding">
         <soap:address location="http://services.xmethods.net:80/perl/soaplite.cgi"
/>
      </port>
   </service>
</definitions>

The following are the major components of the WSDL file:

Component | Definition
definitions | The root element of the WSDL file. This area contains namespace definitions that you use to avoid naming conflicts between multiple web services.
types | (not shown) Defines data types used by the service’s messages.
message | Defines the data transferred by a web service operation, typically the name and data type of input parameters and return values.
port type | Defines one or more operations provided by the web service.
operation | Defines an operation that can be remotely invoked.
input | Specifies an input parameter to the operation using a previously defined message.
output | Specifies the return values from the operation using a previously defined message.
fault | (not shown) Optionally specifies an error message returned from the operation.
binding | Specifies the protocol used to access a web service including SOAP, HTTP GET and POST, and MIME.
service | Defines a group of related operations.
port | Defines an operation and its associated inputs and outputs.

For additional descriptions of the contents of this WSDL file, see Consuming web services.


Consuming web services

ColdFusion provides two methods for consuming web services. The method that you choose depends on your ColdFusion programming style and application.

The following table describes these methods:

Method | CFML operator | Description
CFScript | CreateObject() | Consumes a web service from within a CFScript block
CFML tag | cfinvoke | Consumes a web service from within a block of CFML code

One important consideration is that all consumption methods use the same underlying technology and offer the same performance.


About the examples in this section

The examples in this section reference the BabelFish web service from AltaVista. BabelFish can translate string up to 5 KB in length from one language to another. You can read the WSDL file for this web service in Reading a WSDL file.

If you add the BabelFish web service in Dreamweaver MX, you see the following description of it in the Application panel. For information on adding a web service in Dreamweaver, see Viewing a WSDL file using Dreamweaver MX.

This is a picture of the feature being described.

For more information on BabelFish, see http://babelfish.altavista.com/.


Passing parameters to a web service

One type of information in the WSDL file defines the web service operations and the input and output parameters of each operation, including the data type of each parameter. If you register the web service in Dreamweaver MX, as shown in the previous section, you see that the data type of both input parameters is string.

The following example shows a portion of the WSDL file for the BabelFish web service:

<message name="BabelFishRequest">
   <part name="translationmode" type="xsd:string" />
   <part name="sourcedata" type="xsd:string" />
</message>
<message name="BabelFishResponse">
   <part name="return" type="xsd:string" />
</message>
<portType name="BabelFishPortType">
   <operation name="BabelFish">
      <input message="tns:BabelFishRequest" />
      <output message="tns:BabelFishResponse" />
   </operation>
</portType>

The operation name used in the examples in this section is BabelFish. This operation takes a single input parameter defined as a message of type BabelFishRequest.

You can see that the message BabelFishRequest contains two string parameters: translationmode and sourcedata. When you call the BabelFish operation, you pass both parameters as input.


Handling return values from a web service

Web service operations often return information back to your application. You can determine the name and data type of returned information by examining the WSDL file for the web service.

If you register the web service in Dreamweaver MX, you see that the data type of the return value is string.

The following example shows a portion of the WSDL file for the BabelFish web service:

<message name="BabelFishRequest">
   <part name="translationmode" type="xsd:string" />
   <part name="sourcedata" type="xsd:string" />
</message>
<message name="BabelFishResponse">
   <part name="return" type="xsd:string" />
</message>
<portType name="BabelFishPortType">
   <operation name="BabelFish">
      <input message="tns:BabelFishRequest" />
      <output message="tns:BabelFishResponse" />
   </operation>
</portType>

The operation BabelFish returns a message of type BabelFishResponse. The message statement in the WSDL file defines the BabelFishResponse message as containing a single string parameter named return.


Using cfinvoke to consume a web service

This section describes how to consume a web service using the cfinvoke tag. With the cfinvoke tag, you reference the WSDL file and invoke an operation on the web service with a single tag.

The cfinvoke tag has the following syntax:

<cfinvoke
   webservice = "URLtoWSDL"
   method = "operationName"
   inputParam1 = "val1"
   inputParam2 = "val2"
   ...
   returnVariable = "varName"
>

where:

  • webservice specifies the URL to the WSDL file for the web service.
  • method specifies the operation of the web service to invoke.
  • inputParamN specifies an input parameter passed to the operation.
  • returnVariable specifies the name of the variable containg any results returned from the web service.

To access a web service using cfinvoke:

  1. Create a ColdFusion page with the following content:
    2. <cfinvoke
   webservice = "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"
   method = "BabelFish"
   translationmode = "en_es"
   sourcedata = "Hello world, friend"
   returnVariable = "foo">
<cfoutput>#foo#</cfoutput>
  2. Save the page as wscfc.cfm in your web root directory.
  3. View the page in your browser.

    4. The following string appears in your browser:

    Hola mundo, amigo

You can pass parameters to web services using two other mechanisms: the cfinvokeargument tag and the argumentCollection attribute of the cfinvoke tag.

To pass parameters using the cfinvokeargument tag, you write your call to the web service, as the following code shows:

<cfinvoke
   webservice ="http://www.xmethods.net/sd/2001/BabelFishService.wsdl"
   method ="BabelFish"
   returnVariable = "varName" >
      <cfinvokeargument name="translationmode" value="en_es">
      <cfinvokeargument name="sourcedata" value="Hello world, friend">
</cfinvoke>
<cfoutput>#varName#</cfoutput>

The cfinvokeargument tag is a nested tag of the cfinvoke tag that lets you specify the name and value of a parameter passed to the web service.

You can also use an attribute collection to pass parameters. An attribute collections is a structure where each structure key corresponds to a parameter name and each structure value is the parameter value passed for the corresponding key. The following example shows an invocation of a web service using an attribute collection:

<cfscript>
   stArgs = structNew();
   stArgs.translationmode = "en_es";
   stArgs.sourceData= "Hello world, friend";
</cfscript>

<cfinvoke
   webservice = "http://www.xmethods.net/sd/2001/BabelFishService.wsdl"
   method     = "BabelFish"
   argumentCollection = "#stArgs#"
   returnVariable = "varName" >
<cfoutput>#varName#</cfoutput>

In this example, you create the structure in a CFScript block, but you can use any ColdFusion method to create the structure.


Using CFScript to consume a web service

The example in this section uses CFScript to consume a web service. In CFScript, you use the CreateObject function to connect to the web service. After connecting, you can make requests to the service. The CreateObject function has the following syntax:

webServiceName = CreateObject("webservice", "URLtoWSDL")

where URLtoWSDL specifies the URL to the WSDL file for the web service.

After creating the web service object, you can call operations of the web service using dot notation, in the following form:

webServiceName.operationName(inputVal1, inputVal2, ... )

You can handle return values from web services by writing them to a variable, as the following example shows:

resultVar = webServiceName.operationName(inputVal1, inputVal2, ... );

Or, you can pass the return values directly to a function, such as the writeOutput function, as follows:

writeoutput(webServiceName.operationName(inputVal1, inputVal2, ...) );

To access a web service from CFScript:

  1. Create a ColdFusion page with the following content:
    2. <cfscript>
   ws = CreateObject("webservice",
            "http://www.xmethods.net/sd/2001/BabelFishService.wsdl");
   xlatstring = ws.BabelFish("en_es", "Hello world, friend");
   writeoutput(xlatstring);
</cfscript>
  2. Save the page as wscfscript.cfm in your web root directory.
  3. View the page in your browser.

    4. The following string appears in your browser:

    Hola mundo, amigo

You can also use named parameters to pass information to a web service. The following example performs the same operation as above, except that it uses named parameters to make the web service request:

<cfscript>
   ws = createObject("webservice",
"http://www.xmethods.net/sd/2001/BabelFishService.wsdl");
   xlatstring = ws.BabelFish(translationmode = "en_es",
               sourcedata = "Hello world, friend");
</cfscript>
<cfoutput>#xlatstring#</cfoutput>


Calling web services from a Flash client

The Flash Remoting service lets you call ColdFusion pages from a Flash Client, but it does not let you call web services directly. To call web services from a Flash client, you can use Flash Remoting to call a ColdFusion component that calls the web service. The Flash client can pass input parameters to the component, and the component can return to the Flash client any data returned by the web service.

For more information on Flash Remoting, see Using the Flash Remoting service.


Catching errors when consuming web services

Web services may throw errors, including SOAP faults, during processing that you can catch in your application. If uncaught, these errors propagate to the browser.

To catch errors, you specify an error type of application to the ColdFusion cfcatch tag, as the following example shows:

<cftry>
   Put your application code here ...
   <cfcatch type="application">
      <!--- Add exception processing code here ... --->
   </cfcatch>
   .
   .
   .
   <cfcatch type="Any">
      <!--- Add exception processing code appropriate for all other
exceptions here ... --->
   </cfcatch>
</cftry>

For more information on error handling, see Handling Errors.


Handling inout and out parameters

Some web services define inout and out parameters. You use out parameters to pass a placeholder for a return value to a web service. The web service then returns its result by writing it to the out parameter. Inout parameters let you pass a value to a web service and lets the web service return its result by overwriting the parameter value.

The following example shows a web service that takes as input an inout parameter containing a string and writes its results back to the string:

<cfset S="foo">
<cfscript>
   ws=createobject("webservice", "URLtoWSDL")
   ws.modifyString("S");
<cfscript>
<cfoutput>#S#</cfoutput>

Even though this web service takes as input the value of S, because you pass it as an inout parameter you do not enclose it in pound signs.

Note: ColdFusion supports the use of inout and out parameters to consume web services. However, ColdFusion does not support inout and out parameters when creating web services for publication.


Configuring web services in the ColdFusion Administrator

The ColdFusion Administrator lets you register web services so that you do not have to specify the entire WSDL URL when you reference the web service.

Note: The first time you reference a web service, ColdFusion automatically registers it in the Administrator.

For example, the following code references the URL to the BabelFish WSDL file:

<cfscript>
   ws = CreateObject("webservice",
"http://www.xmethods.net/sd/2001/BabelFishService.wsdl");
   xlatstring = ws.BabelFish("en_es", "Hello world, friend");
   writeoutput(xlatstring);
</cfscript>

If you register the BabelFish web service in the ColdFusion Administrator using, for example, the name wsBabel, you could then reference the web service as follows:

<cfscript>
   ws = CreateObject("webservice", "wsBabel");
   xlatstring = ws.BabelFish("en_es", "Hello world, friend");
   writeoutput(xlatstring);
</cfscript>

Not only does this enable you to shorten your code, registering a web service in the ColdFusion Administrator lets you change a web service’s URL without modifying your code. So, if the BabelFish web service moves to a new location, you only update the administrator setting; not your application code.

For more information, see the online help in the ColdFusion Administrator.


Data conversions between ColdFusion and WSDL data types

A WSDL file defines the input and return parameters of an operation, including data types. For example, the BabelFish web service contains the following definition of input and return parameters:

<message name="BabelFishRequest">
      <part name="translationmode" type="xsd:string" />
      <part name="sourcedata" type="xsd:string" />
   </message>
   <message name="BabelFishResponse">
      <part name="return" type="xsd:string" />
</message>

As part of consuming web services, you must understand how ColdFusion converts WSDL defined data types to ColdFusion data types. The following table shows this conversion:

ColdFusion data type | WSDL data type
numeric | SOAP-ENC:double
boolean | SOAP-ENC:boolean
string | SOAP-ENC:string
array | SOAP-ENC:Array
binary | xsd:base64Binary
date | xsd:dateTime
void (operation returns nothing) |
struct | complex type

For many of the most common data types, such as string and numeric, a WSDL data type maps directly to a ColdFusion data type. For complex WSDL data types, the mapping is not as straight forward. In many cases, you map a complex WSDL data type to a ColdFusion structure. For more information on handling complex data types, see Handling complex data types.


Consuming ColdFusion web services

Your application might consume web services created in ColdFusion. You do not have to perform any special processing on the input parameters or return values because ColdFusion handles data mappings automatically when consuming a ColdFusion web service.

For example, when ColdFusion publishes a web service that returns a query, or takes a query as an input, the WSDL file for that service lists its data type as QueryBean. However, a ColdFusion application consuming this web service can pass a ColdFusion query object to the function as an input, or write a returned QueryBean to a ColdFusion query object.

Note: For a list of how ColdFusion data types map to WSDL data types, see Data conversions between ColdFusion and WSDL data types.

The following example shows a ColdFusion component that takes a query as input and echoes the query back to the caller:

<cfcomponent>
   <cffunction name='echoQuery' returnType='query' access='remote'>
      <cfargument name='input' type='query'>
      <cfreturn #arguments.input#>
   </cffunction>
</cfcomponent>

If you add this web service in Dreamweaver MX, you see the following description of it in the Application panel.

This is a picture of the feature being described.

Note: This figure assumes that you create a web component named echotypes.cfc that contains the echoQuery function definition shown above, and write echotypes.cfc to your web root directory.

In the WSDL file for the echotypes.cfc component, you see the following definitions that specify the type of the function’s input and output as QueryBean:

<wsdl:message name="echoQueryRequest">
   <wsdl:part name="input" type="tns1:QueryBean"/>
</wsdl:message>
<wsdl:message name="echoQueryResponse">
   <wsdl:part name="return" type="tns1:QueryBean"/>
</wsdl:message>

Since ColdFusion automatically handles mappings to ColdFusion data types, you can call this web service as the following example shows:

<head>
<title>Passing queries to web services</title>
</head>
<body>
<cfquery name="GetEmployees" datasource="CompanyInfo">
   SELECT FirstName, LastName, Salary
   FROM Employee
</cfquery>

<cfinvoke
   webservice = "http://localhost/echotypes.cfc?wsdl"
   method = "echoQuery"
   input="#GetEmployees#"
   returnVariable = "returnedQuery">

<cfoutput>
   Is returned result a query? #isQuery(returnedQuery)# <br><br>
</cfoutput>

<cfoutput query="returnedQuery">
   #FirstName#
   #LastName#
   #Salary#<br>
</cfoutput>
</body>


Publishing web services

To publish web services for consumption by remote applications, you create the web service using ColdFusion components. For more information on components, see Building and Using ColdFusion Components.


Creating components for web services

ColdFusion components encapsulate application functionality and provide a standard interface for client access to that functionality. A component typically contains one or more functions defined by the cffunction tag.

For example, the following component contains a single function:

<cfcomponent>
   <cffunction name="echoString" returnType="string" output="no">
      <cfargument name="input" type="string">
      <cfreturn #arguments.input#>
   </cffunction>
</cfcomponent>

The function, named echoString, echoes back any string passed to it. To publish the function as a web service, you must modify the function definition to add the access attribute, as the following example shows:

<cffunction name="echoString" returnType="string" output="no" access="remote" >

By defining the function as remote, ColdFusion includes the function in the WSDL file. Only those functions marked as remote are accessible as a web service.

The following list defines the requirements for how to create web services for publication:

  1. The value of the access attribute of the cffunction tag must be remote.
  2. The cffunction tag must include the returnType attribute to specify a return type.

    3. If the function does not return anything, set its returnType attribute to void.

  3. The output attribute of the cffunction tag must be set to No because ColdFusion converts all output to XML to return it to the consumer.
  4. The attribute setting required="false" for the cfargument tag is ignored. ColdFusion considers all parameters as required.


Specifying data types of function arguments and return values

The cffunction tag lets you define a single return value and one or more input parameters passed to a function. As part of the function definition, you include the data type of the return value and input parameters.

The following example shows a component that defines a function with a return value of type string, one input parameter of type string, and one input parameter of type numeric:

<cfcomponent>
   <cffunction name="trimString" returnType="string" output="no">
      <cfargument name="inString" type="string">
      <cfargument name="trimLength" type="numeric">
   </cffunction>
</cfcomponent>

As part of publishing the component for access as a web service, ColdFusion generates the WSDL file that defines the component where the WSDL file includes definitions for how ColdFusion data types map to WSDL data types. The following table shows this mapping:

ColdFusion data type | WSDL data type
numeric | SOAP-ENC:double
boolean | SOAP-ENC:boolean
string | SOAP-ENC:string
array | SOAP-ENC:Array
binary | xsd:base64Binary
date | xsd:dateTime
guid | SOAP-ENC:string
uuid | SOAP-ENC:string
void (operation returns nothing) |
struct | Map
query | QueryBean
any | complex type
component definition | complex type

In most cases, consumers of ColdFusion web services will be able to easily pass data to and return results from component functions by mapping their data types to the WSDL data types shown above.

For ColdFusion structures and queries, clients may have to perform some processing to map their data to the correct type. For more information, see Publishing web services that use complex data types.

You can also define a data type in one ColdFusion component based on another component definition. For more information on using components to specify a data type, see Using ColdFusion components to define data types for web services.


Producing WSDL files

ColdFusion automatically creates a WSDL file for any component referenced as a web service. For example, if you have a component named echo.cfc in your web root directory, you can view its corresponding WSDL file by requesting the component as follows:

http://localhost/echo.cfc?wsdl

For example, you define a ColdFusion component as follows:

<cfcomponent>
   <cffunction
name = "echoString"
returnType = "string"
output = "no"
access = "remote">
      <cfargument name = "input" type = "string">
      <cfreturn #arguments.input#>
   </cffunction>
</cfcomponent>

If you register the component in Dreamweaver MX, it appears in the Application panel as shown below.

This is a picture of the feature being described.

Requesting the WSDL file returns the following:

<?xml version="1.0" encoding="UTF-8" ?>
<wsdl:definitions targetNamespace="http://webservices"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:intf="http://webservices"
xmlns:impl="http://webservices-impl"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns="http://schemas.xmlsoap.org/wsdl/">
   <wsdl:message name="echoStringResponse">
         <wsdl:part name="return" type="SOAP-ENC:string" />
   </wsdl:message>
   <wsdl:message name="echoStringRequest">
      <wsdl:part name="input" type="SOAP-ENC:string" />
   </wsdl:message>
   <wsdl:portType name="echo">
      <wsdl:operation name="echoString" parameterOrder="in0">
         <wsdl:input message="intf:echoStringRequest" />
         <wsdl:output message="intf:echoStringResponse" />
      </wsdl:operation>
   </wsdl:portType>
   <wsdl:binding name="echo.cfcSoapBinding" type="intf:echo">
      <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/
http" />
      <wsdl:operation name="echoString">
         <wsdlsoap:operation soapAction="" style="rpc" />
         <wsdl:input>
            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/
soap/encoding/" namespace="http://webservices" />
         </wsdl:input>
         <wsdl:output>
            <wsdlsoap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/
soap/encoding/" namespace="http://webservices" />
         </wsdl:output>
      </wsdl:operation>
   </wsdl:binding>
   <wsdl:service name="echo.cfcService">
      <wsdl:port name="echo.cfc" binding="intf:echo.cfcSoapBinding">
         <wsdlsoap:address location="http://SMGILSON02/webservices/echo.cfc" />
      </wsdl:port>
   </wsdl:service>
</wsdl:definitions>

To publish a web service:

  1. Create a ColdFusion page with the following content:
    2. <cfcomponent output="false">
   <cffunction
         name = "echoString"
         returnType = "string"
         output = "no"
         access = "remote">
      <cfargument name = "input" type = "string">
      <cfreturn #arguments.input#>
   </cffunction>
</cfcomponent>
  2. Save this file as echo.cfc in your web root directory.
  3. Create a ColdFusion page with the following content:
    4. <cfinvoke webservice ="http://localhost/echo.cfc?wsdl"
   method ="echoString"
   input = "hello"
   returnVariable="foo">

<cfoutput>#foo#</cfoutput>
  4. Save this file as echoclient.cfm in your web root directory.
  5. Request echoclient.cfm in your browser.

    6. The following string appears in your browser:

    hello

You can also invoke the web service using the following code:

<cfscript>
   ws = CreateObject("webservice", "http://localhost/echo.cfc?wsdl");
   wsresults = ws.echoString("hello");
   writeoutput(wsresults);
</cfscript>


Using ColdFusion components to define data types for web services

ColdFusion components let you define both methods and properties of the component. Once defined, you can use components to define data types for web services. The following code defines a component in the file address.cfc:

<cfcomponent>
   <cfproperty name="Number" type="numeric">
   <cfproperty name="Street" type="string">
   <cfproperty name="City" type="string">
   <cfproperty name="State" type="string">
   <cfproperty name="Country" type="string">
</cfcomponent>

This component contains properties that represent a street address. The following code defines a component in the file name.cfc that defines first and last name properties:

<cfcomponent>
   <cfproperty name="Firstname" type="string">
   <cfproperty name="Lastname" type="string">
</cfcomponent>

You can then use address and name to define data types in a ColdFusion component created to publish a web service, as the following example shows:

<cfcomponent>
   <cffunction name="echoName" returnType="name" access="remote">
         <cfargument name="input" type="name">
         <cfreturn #arguments.input#>
   </cffunction>

   <cffunction name="echoAddress" returnType="address" access="remote">
         <cfargument name="input" type="address">
         <cfreturn #arguments.input#>
   </cffunction>
</cfcomponent>

Note: If the component files are not in a directory under your web root, you must create a ColdFusion mapping to the directory containing them.

If you register the component in Dreamweaver MX, it appears in the Application panel as shown below.

This is a picture of the feature being described.

The WSDL file for the web service contains data definitions for the complex types name and address. Each definition consists of the elements that define the type as specified in the ColdFusion component file for that type. For example, shown below is the definition for name:

<complexType name="name">
   <all>
      <element name="Firstname" nillable="true" type="xsd:string" />
      <element name="Lastname" nillable="true" type="xsd:string" />
   </all>
</complexType>


Securing your web services

You can restrict access to your published web services to control the users allowed to invoke them. You can use your web server to control access to the directories containing your web services, or you can use ColdFusion security in the same way that you would to control access to any ColdFusion page.


Controlling access to component CFC files

To browse the HTML description of a .cfc file, you request the file by specifying a URL to the file in your browser. By default, ColdFusion secures access to all URLs that directly reference a .cfc file, and prompts you to enter a password upon the request. Use the ColdFusion RDS password to view the file.

To disable security on .cfc file browsing, use the ColdFusion Administrator to disable the RDS password.

For more information, see Building and Using ColdFusion Components.


Using your web server to control access

Most web servers, including IIS and Apache, implement directory access protection using the basic HTTP authentication mechanism. When a client attempts to access one of the resources under a protected directory, and has not properly authenticated, the web server automatically sends back an authentication challenge, typically an HTTP Error 401 Access Denied error.

In response, the client’s browser opens a login prompt containing a username and password field. When the user submits this information, the browser sends it back to the web server. If authentication passes, the web server allows access to the directory. The browser also caches the authentication data as long as it is open, so subsequent requests automatically include the authentication data.

Web service clients can also pass the username and password information as part of the request. The cfinvoke tag includes the username and password attributes that let you pass login information to a web server using HTTP basic authentication. You can include these attributes when invoking a web service, as the following example shows:

<cfinvoke
   webservice = "http://some.wsdl"
   returnVariable = "foo"
   ...
   username="aName"
   password="aPassword">
<cfoutput>#foo#</cfoutput>

ColdFusion inserts the username/password string in the authorization request header as a base64 binary encoded string, with a colon separating the username and password. This method of passing the username/password is compatible with the HTTP basic authentication mechanism used by web servers.

The ColdFusion Administrator lets you predefine web services. As part of defining the web service, you can specify the username and password that ColdFusion includes as part of the request to the web service. Therefore, you do not have to encode this information using the cfinvoke tag. For information on defining a web service in the ColdFusion Administrator, see Configuring web services in the ColdFusion Administrator.


Using ColdFusion to control access

Instead of letting the web server control access to your web services, you can handle the username/password string in your Application.cfm file as part of your own security mechanism. In this case, you use the cflogin tag to retrieve the username/password information from the authorization header, decode the binary string, and extract the username and password, as the following example Application.cfm shows:

<cfsilent>
<cflogin>

   <cfset isAuthorized = false>

   <cfif isDefined("cflogin")
      <!--- verify user name from cflogin.name and password from cflogin.password
using your authentication mechanism --->
      >
      <cfset isAuthorized = true>
   </cfif>

</cflogin>

<cfif not isAuthorized>
   <!--- If the user does not pass a username/password, return a 401 error.
      The browser then prompts the user for a username/password. --->
   <cfheader statuscode="401">
   <cfheader name="WWW-Authenticate" value="Basic realm=""Test""">
   <cfabort>
</cfif>
</cfsilent>

This example does not show how to perform user verification. For more information on verification, see Securing Applications.


Assigning security roles to functions

ColdFusion components offer role-based security. The following example creates a component method that deletes files:

<cfcomponent>
   <cffunction name="deleteFile" access="remote" roles="admin,manager">
      <cfargument name="filepath" required="yes">
      <cffile action="DELETE" file=#arguments.filepath#>
   </cffunction>
</cfcomponent>

In the example, the cffunction tag includes the roles attribute to specify the user roles allowed to access it. In this example, only users in the role admin and manager can access the function. Notice that multiple roles are delimited by a comma.

Role based security can be used with any ColdFusion component, not just for web services. For more information on roles, see Securing Applications.


Using programmatic security

You can implement your own security within the a function to protect resources. For example you can use the ColdFusion function IsUserInRole() to determine if a user is in particular role, as the following example shows:

<cffunction name="foo">
   <cfif IsUserInRole("admin")>
      … do stuff allowed for admin
   <cfelseif IsUserInRole("user")>
      … do stuff allowed for user
   <cfelse>
      <cfoutput>unauthorized access</cfoutput>
      <cfabort>
   </cfif>
</cffunction>


Best practices for publishing web services

ColdFusion web services provide a powerful mechanism for publishing and consuming application functionality. However, before you produce web services for publication, you might want to consider the following best practices:

  1. Minimize the use of ColdFusion complex types, such as query and struct, in the web services you create for publication. These types require consumers, especially those consuming the web service using a technology other than ColdFusion, to create special data structures to handle complex types.
  2. Locally test the ColdFusion components implemented for web services before publishing them over the Internet.


Handling complex data types

When dealing with web services, handling complex types falls into the following categories:

  • Mapping the data types of a web service that you want to consume to ColdFusion data types
  • Understanding how clients will reference your ColdFusion data types when you publish a web service

This section describes both categories.


Consuming web services that use complex data types

The following table shows how WSDL data types are converted to ColdFusion data types:

ColdFusion data type | WSDL data type
numeric | SOAP-ENC:double
boolean | SOAP-ENC:boolean
string | SOAP-ENC:string
array | SOAP-ENC:Array
binary | xsd:base64Binary
date | xsd:dateTime
void (operation returns nothing) |
struct* | complex type

This table shows that complex data types map to ColdFusion structures. ColdFusion structures offer a flexible way to represent data. You can create structures that contain single-dimension arrays, multi-dimensional arrays, and other structures.

The ColdFusion mapping of complex types to structures is not automatic. You have to perform some processing on the data in order to access it as a structure. The next sections describe how to pass complex types to web services, and how to handle complex types returned from web services.


Passing input parameters to web services as complex types

A web service can take a complex data type as input. In this situation, you can construct a ColdFusion structure that models the complex data type, then pass the structure to the web service.

For example, the following excerpt from a WSDL file shows the definition of a complex type named Employee:

<s:complexType name="Employee">
   <s:sequence>
      <s:element minOccurs="1" maxOccurs="1" name="fname" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="lname" type="s:string" />
      <s:element minOccurs="1" maxOccurs="1" name="active" type="s:boolean" />
      <s:element minOccurs="1" maxOccurs="1" name="age" type="s:int" />
      <s:element minOccurs="1" maxOccurs="1" name="hiredate" type="s:dateTime" />
      <s:element minOccurs="1" maxOccurs="1" name="number" type="s:double" />
   </s:sequence>
</s:complexType>

The Employee data type definition includes six elements, the data type of each element, and the name of each element.

Another excerpt from the WSDL file shows a message definition using the Employee data type. This message defines an input parameter, as the following code shows:

<message name="updateEmployeeInfoSoapIn">
   <part name="thestruct" type="s0:Employee" />
</message>

A third excerpt from the WSDL file shows the definition of an operation, named updateEmployeeInfo, possibly one that updates the employee database with the employee information. This operation takes as input a parameter of type Employee, as the following code shows:

<operation name="updateEmployeeInfo">
   <input message="s0:updateEmployeeInfoSoapIn" />
</operation>

To call the updateEmployeeInfo operation, you create a ColdFusion structure, initialize six fields of the structure that correspond to the six elements of Employee, then call the operation, as the following code shows:

<!--- Create a structure using CFScript, then call the web service. --->
<cfscript>
   stUser = structNew();
   stUser.active = TRUE;
   stUser.fname = "John";
   stUser.lname = "Smith";
   stUser.age = 23;
   stUser.hiredate = createDate(2002,02,22);
   stUser.number = 123.321;

   ws = createObject("webservice", "http://somehost/echosimple.asmx?wsdl");
   ws.echoStruct(stUser);

</cfscript>

You can use structures for passing input parameters as complex types in many situations. However, to build a structure to model a complex type, you have to inspect the WSDL file for the web service to determine the layout of the complex type. This can take some practice.


Handling return values as complex types

When a web service returns a complex type, you can write that returned value directly to a ColdFusion variable.

The previous section used a complex data type named Employee to define an input parameter to an operation. A WSDL file can also define a return value using the Employee type, as the following code shows:

<message name="updateEmployeeInfoSoapOut">
   <part name="updateEmployeeInfoResult" type="s0:Employee" />
</message>
<operation name="updateEmployeeInfo">
   <input message="s0:updateEmployeeInfoSoapIn" />
   <output message="s0:updateEmployeeInfoSoapOut" />
</operation>

In this example, the operation updateEmployeeInfo takes a complex type as input and returns a complex type as output. To handle the input parameter, you create a structure. To handle the returned value, you write it to a ColdFusion variable, as the following example shows:

<!--- Create a structure using CFScript, then call the web service. --->
<!--- Write the returned value to a ColdFusion variable. --->
<cfscript>
   stUser = structNew();
   stUser.active = TRUE;
   stUser.fname = "John";
   stUser.lname = "Smith";
   stUser.age = 23;
   stUser.hiredate = createDate(2002,02,22);
   stUser.number = 123.321;

   ws = createObject("webservice", "http://somehost/echosimple.asmx?wsdl");
   myReturnVar = ws.echoStruct(stUser);

</cfscript>

<!--- Output the returned values. --->
<cfoutput>
   <br>
   <br>Name of employee is: #myReturnVar.fname#  #myReturnVar.lname#
   <br>Active status: #myReturnVar.active#
   <br>Age:  #myReturnVar.age#
   <br>Hire Date: #myReturnVar.hiredate#
   <br>Favorite Number: #myReturnVar.number#
</cfoutput>

You access elements of the variable myReturnVar using the "dot" notation in the same way you access structure fields. If a complex type has nested elements, in the way a structure can have multiple levels of nested fields, you use "dot" notation to access the nested elements, as in a.b.c.d, to whatever nesting level is necessary.

However, the variable myReturnVar is not a ColdFusion structure. It is a container for the complex type, but has none of the attributes of a ColdFusion structure. Calling the ColdFusion function isStruct on the variable returns "False".

You can copy the contents of the variable to a ColdFusion structure, as the following example shows:

<cfscript>
...
   ws = createObject("webservice", "http://somehost/echosimple.asmx?wsdl");
   myReturnVar = ws.echoStruct(stUser);

   realStruct = structNew();
   realStruct.active = #myReturnVar.active#;
   realStruct.fname = "#myReturnVar.fname#";
   realStruct.lname = "#myReturnVar.lname#";
   realStruct.age = #myReturnVar.age#;
   realStruct.hiredate = #myReturnVar.hiredate#;
   realStruct.number = #myReturnVar.number#;

</cfscript>

Calling isStruct on realStruct returns "True" and you can use all ColdFusion structure functions to process it.

This example shows that ColdFusion variables and structures are useful for handling complex types returned from web services. To understand how to access the elements of a complex type written to a ColdFusion variable, you have to inspect the WSDL file for the web service. The WSDL file defines the API to the web service and will provide you with the information necessary to handle data returned from it.


Publishing web services that use complex data types

The two ColdFusion data types that do not map exactly to WSDL data types are struct and query. When you publish a ColdFusion web service that uses parameters of type struct or query, the consuming application needs to be able to handle the data.

Note: If the consumer of a ColdFusion web service is another ColdFusion application, you do not have to perform any special processing. ColdFusion correctly maps struct and query data types in the web service publisher with the consumer. For more information, see Consuming ColdFusion web services.


Publishing structures

A ColdFusion structure can hold an unlimited number of key-value pairs where the values can be of any ColdFusion data type. While it is a very useful and powerful way to represent data, it cannot be directly mapped to any XML data types defined in the SOAP 1.1 encoding and XML Schema specification. Therefore, ColdFusion structures are treated as a custom type and the complex type XML schema in WSDL looks like the following:

<complexType name="Map">
   <sequence>
      <element name="item" minOccurs="0" maxOccurs="unbounded">
         <complexType>
            <all>
               <element name="key" type="xsd:anyType" />
               <element name="value" type="xsd:anyType" />
            </all>
         </complexType>
      </element>
   </sequence>
</complexType>

This complex type defines a representation of a structure, where the structure keys and values can be any type.

If you register the component in Dreamweaver MX, it appears in the Application panel as shown below.

This is a picture of the feature being described.

In the WSDL mapping of a ColdFusion structure, each key/value pair in the structure points to the next element in the structure except for the final field, which contains a value. For example, if you have a structure containing the field A.B.C, that field is represented as the following figure shows:

This is a picture of the feature being described.


Publishing queries

ColdFusion publishes query data types as the WSDL type QueryBean. The QueryBean data type contains two elements, as the following excerpt from a WSDL file shows:

<complexType name="QueryBean">
   <all>
      <element name="data" nillable="true" type="intf:ArrayOf_SOAP-ENC_Array" />
      <element name="ColumnList" nillable="true"
type="intf:ArrayOf_SOAP-ENC_string" />
   </all>
</complexType>

The following table describes the elements of QueryBean:

Element name | Description
ColumnList | String array that contains column names
data | 2-dimensional array that contains query data

The WSDL file for a QueryBean defines these elements as follows:

<complexType name="ArrayOf_SOAP-ENC_Array">
   <complexContent>
      <restriction base="SOAP-ENC:Array">
         <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="SOAP-ENC:Array[]" />
      </restriction>
   </complexContent>
</complexType>
<complexType name="ArrayOf_SOAP-ENC_string">
   <complexContent>
   <restriction base="SOAP-ENC:Array">
      <attribute ref="SOAP-ENC:arrayType" wsdl:arrayType="xsd:string[]" />
   </restriction>
   </complexContent>
</complexType>
Previous


Integrating J2EE and Java Elements in CFML Applications

This chapter describes how to integrate J2EE elements, including the following into your ColdFusion application.

  • JSP pages and servlets
  • JSP tags
  • Java objects, including Enterprise JavaBeans (EJBs)

It does not explain J2EE concepts or how to program using Java or JSP. It does explain how to use existing Java and JSP elements in your ColdFusion Applications.

Contents
  • About ColdFusion, Java, and J2EE
  • Using JSP tags and tag libraries
  • Interoperating with JSP pages and servlets
  • Using Java objects
Next


About ColdFusion, Java, and J2EE

ColdFusion is built on a J2EE-compliant Java technology platform. This lets ColdFusion applications take advantage of, and integrate with, J2EE elements. ColdFusion pages can do any of the following:

  • Include JavaScript and client-side Java applets on the page
  • Use JSP tags
  • Interoperate with JSP pages
  • Use Java servlets
  • Use Java objects, including JavaBeans and Enterprise JavaBeans


About ColdFusion and client-side JavaScript and applets

ColdFusion pages, like HTML pages, can incorporate client-side JavaScript and Java applets. To use JavaScript, you write the JavaScript code just as you do on any HTML page. ColdFusion ignores the JavaScript and sends it to the client.

The cfapplet tag simplifies using Java client-side applets. To use an applet on a ColdFusion page, do the following:

  • Register the applet .class file in ColdFusion Administrator Java Applets Extensions page. (For information on registering applets, see the ColdFusion Administrator Help.)
  • Use the cfapplet tag to call the applet. The appletSource attribute must be the Applet name assigned in ColdFusion Administrator.

For example, ColdFusion includes a Copytext sample applet that copies text from one text box to another. The ColdFusion Setup automatically registers the applet in the Administrator. To use this applet, incorporate it on your page. For example:

<cfform action = "copytext.cfm">
  <cfapplet appletsource = "copytext" name = "copytext">
</cfform>


About ColdFusion and JSP

ColdFusion supports JSP tags and pages in the following ways:

  • Interoperates with JSP pages: ColdFusion pages can include or forward to JSP pages, JSP pages can include or forward to ColdFusion pages, and both types of pages can share data in persistent scopes.
  • Imports and uses JSP tag libraries: the cfimport tag imports JSP tag libraries and lets you use its tags.

ColdFusion pages are not JSP pages, however, and you cannot use most JSP syntax on CFML pages. In particular you cannot use the following features on CFML pages:

  • Include, Taglib and Page directives Instead, you use CFML include and import tags to include pages and import tag libraries.
  • Expression, Declaration, and Scriptlet JSP scripting elements Instead, you use CFML elements and expressions.
  • JSP comments Instead, you use CFML comments. (ColdFusion ignores JSP comments and passes them to the browser.)
  • Standard JSP tags such as jsp:plugin, unless your J2EE server provides access to these tags in a jar file. Instead, you use ColdFusion tags and the PageContext object.


About ColdFusion and Servlets

Some Java servlets are not exposed as JSP pages; instead they are Java programs. You can incorporate JSP servlets in your ColdFusion application. For example, your enterprise might have an existing servlet that performs some business logic. To use a servlet, the ColdFusion page specifies the servlet by using the ColdFusion GetPageContext function.

When you access the servlet with the GetPageContext function, the ColdFusion page shares the Application, Session, and Request scopes with the servlet, so you can use these scopes for shared data.

ColdFusion pages can also access servlets by using the cfhttp tag, use the servlet URL in a form tag, or access an SHTML page that uses a servlet tag.

Note: The cfservlet tag, which provides access to servlets on JRun servers, is deprecated for ColdFusion MX.


About ColdFusion and Java objects

Java objects include the following:

  • Standard Java classes and methods that make up the J2EE API
  • Custom-written Java objects, including the following:
    • Custom classes, including JavaBeans
    • Enterprise JavaBeans

ColdFusion pages use the cfobject tag to access Java objects.

ColdFusion searches for the objects in the following order:

  1. The ColdFusion Java Dynamic Class Load directories.
    • Java archive (.jar) files in web_root/WEB-INF/lib.
    • Class (.class) files in web_root/WEB-INF/classes.

      • ColdFusion reloads classes from these directories, as described in the following section About class loading.

  2. The classpath specified on the ColdFusion Administrator JVM and Java Settings page.
  3. The default JVM classpath.


About class loading

ColdFusion dynamically loads classes that are either .class files in the web_root/WEB-INF/classes directory or in JAR files in the web_root/WEB-INF/lib directory. ColdFusion checks the time stamp on the file when it creates an object that is defined in either directory, even when the class is already in memory. If the file that contains the class is newer than the class in memory, ColdFusion loads the class from that directory.

To use this feature, make sure that the Java implementation classes that you modify are not in the general JVM classpath.

To disable automatic class loading of your classes, put the classes in the JVM classpath. Classes located on the JVM classpath are loaded once per server lifetime. To reload these classes, stop and restart ColdFusion Server.

Note: Because you put tag libraries in the web_root/WEB-INF/lib directory, ColdFusion automatically reloads these libraries if necessary when you import the library.


About GetPageContext and the PageContext object.

Because ColdFusion pages are J2EE servlet pages, all ColdFusion pages have an underlying Java PageContext object. CFML includes the GetPageContext function that you can then use in your ColdFusion page.

The PageContext object exposes a number of fields and methods that can be useful in J2EE integration. In particular, it includes the include and forward methods that provide the equivalent of the corresponding standard JSP tags.

This chapter describes how to use the include and forward PageContext methods for calling JSP pages and servlets. It does not discuss the PageContext object in general. For more information on the object, see Java documentation. You can find the Javadoc description of this class at http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/jsp/PageContext.html.


Using JSP tags and tag libraries

You can use JSP tags from any JSP tag library. For example, you can use any of the custom tags in the open-source Apache Jakarta Project Taglibs project tag libraries, located at http://jakarta.apache.org/taglibs/index.html. This project consists of a number of individual JSP custom tag libraries for purposes ranging from JNDI access to generating random text strings.


Using a JSP tag in a ColdFusion page

JSP pages use a standard set of tags, such as jsp:forward and jsp:include. You can also import custom JSP tag libraries into a JSP application. You can use both the standard JSP tags and custom JSP tags in ColdFusion pages, as the following sections describe.


Standard JSP tags and ColdFusion

ColdFusion tags provide equivalent features to most standard JSP tags. For example, the cfapplet tag provides the same service as the jsp:plugin tag, and cfobject tag lets you use JavaBeans, as does the jsp:usebean tag. Similarly, you do not use the jsp:getproperty tag because ColdFusion automatically gets properties when you reference them. Therefore, ColdFusion does not support the use of standard JSP tags directly.

However, two standard JSP tags provide functionality that is useful in ColdFusion pages: the forward and include tags invoke JSP pages and Java servlets. The PageContext object described in About GetPageContext and the PageContext object. has forward and include methods that provide the same operations. For more information about using these methods see Accessing a JSP page or servlet from a ColdFusion page.


Using custom JSP tags in a ColdFusion page

Follow these steps to use a a custom JSP tag on a ColdFusion page:

To use a custom tag:

  1. Put the tag library, consisting of the taglibname.jar file, and the taglibname.tld file, if one is supplied, in the web_root/WEB-INF/lib directory.
  2. In the ColdFusion page that uses a JSP tag from the tag library, specify the tag library name in a cfimport tag; for example:
    3. <cfimport taglib="/WEB-INF/lib/random.jar" prefix="random">

If the TLD file is not included in the JAR file, use the .tld suffix in place of the .jar suffix.

    Note: The cfimport tag must be on the page that uses the imported tag. You cannot put the cfimport tag in Application.cfm.
  3. Use the custom tag using the form prefix:tagName; for example:
    4. <random:number id="myNum" range="000000-999999" />

Note: You cannot use the cfsavecontent tag to suppress output of a custom JSP tag.


Example: using the random tag library

The following example uses the random tag library from the Apache Jakarta Taglibs project and calls the library’s number tag, which initializes a random number generator that uses a secure algorithm to generate a six-digit random number. You get a new random number each time you reference the variable randPass.random.

<cfimport taglib="/WEB-INF/lib/random.jar" prefix="myrand">
<myrand:number id="randPass" range="000000-999999" algorithm="SHA1PRNG"
provider="SUN" />
<cfset myPassword = randPass.random>
<cfoutput>
   Your password is #myPassword#<br>
</cfoutput>

For more information on the Jakarta random tag library and how to use its tags, see the documentation at the Apache Jakarta Taglibs project website, http://jakarta.apache.org/taglibs/index.html. The Taglibs project includes many open source custom tag libraries.


Interoperating with JSP pages and servlets

ColdFusion pages and JSP pages can interoperate in several ways:

  • ColdFusion pages can invoke JSP pages and servlets.
  • JSP pages can invoke ColdFusion pages.
  • ColdFusion pages, JSP pages, and servlets can share data in three scopes.

The following sections show how you can use these techniques.


Integrating JSP and servlets in a ColdFusion application

You can integrate JSP pages and servlets in your ColdFusion application. For example, you can write some application pages in JSP and write others in CFML. ColdFusion pages can access JSP pages by using the JSP include and forward methods to call the page. As with any web application, you can use href links in ColdFusion pages to open JSP pages.

The ability to use JSP lets you incorporate legacy JSP pages in your ColdFusion application, or conversely, use CFML to expand an existing JSP application using ColdFusion pages.

If you have a JSP page that must call a CFML page, you also use a jsp:forward or jsp:include tag to call the CFML page. For an example of calling a ColdFusion page from a JSP page, see Calling a JSP page from a CFML page.


Accessing a JSP page or servlet from a ColdFusion page

To access a JSP page or servlet from a ColdFusion page, you use the getPageContext function with the forward or the include method. For example, to include a JSP "Hello World" page in your ColdFusion application, use the following line:

GetPageContext().include("hello.jsp");

To pass parameters to the JSP page, include the parameters in the page URL.

For example, you might want to integrate an existing JSP customer response component into a new ColdFusion order processing application. The order processing application provides the order number, total cost, and expected shipping date, and the customer response component sends the response to the e-mail address on file for the particular customer number. The ColdFusion application might use the following CFScript code to call the response JSP page:

urlParams = "UID=#order.uid#&cost=#order.total#&orderNo=#order.orderNo#
&shipDate=#order.shipDateNo#"
getPageContext().forward(URLEncodedFormat("/responsegen/responsegen.jsp
?#urlParams#"));

To access a servlet that exposes the same functionality, you use the same code, although the URL would change. For example, to run a servlet called HelloWorldServlet, you put the servlet .java or .class file in the serverroot/WEB-INF/classes directory and refer to the servlet with the URL /servlet/HelloWorldServlet.


Sharing data between ColdFusion pages and JSP pages or servlets

If an application includes ColdFusion pages and JSP pages or servlets, they can share data in the Request, Session and Application scopes. The following table lists the ways that you can access JSP pages with which you want to share the scope data:

Scope | Can share data using
Request | forward, include
Session | href, cfhttp, forward, include
Application | href, cfhttp, forward, include

Note: When you share data between ColdFusion pages and JSP pages, you must be careful about data type conversion issues. For more information, see Java and Cold Fusion Data Type Conversions.

To share Session variables, you must specify J2EE session management in the ColdFusion Administrator. For more information on configuring and using J2EE Session scope management, see ColdFusion and J2EE session management .

For example, you could put the customer order structure used in the previous example in the Session scope. Then, you would not have to pass the order values as a set of parameters. Instead, the JSP pages could access the Session scope variables directly, and the ColdFusion page would only require a line like the following to call the JSP page:

getPageContext().forward(URLEncodedFormat("/responsegen/responsegen.jsp"));

For examples of using the Request, Session, and Application scopes to share data between ColdFusion pages and JSP pages, including samples of the appropriate JSP code, see the following section, Examples: using JSP with CFML.


Accessing ColdFusion Application and Session variables in JSP pages

ColdFusion runs as a J2EE application on the J2EE application server. The J2EE application ServletContext is a data structure that stores objects as attributes. A ColdFusion Application scope is represented as an attribute named by the Application scope name. The attribute contains the scope values as a hash table. Therefore, you access ColdFusion Application scope variable in a JSP page or servlet using the following format:

((Map)application.getAttribute("CFApplicationName"))).get("appVarName")

Similarly, the ColdFusion Session scope is a structure within the J2EE session. Because ColdFusion identifies sessions by the application name. the session structure is contained in an attribute of the J2EE session that is identified by the application name. Therefore, you access ColdFusion session variables as follows:

((Map)(session.getAttribute("CFApplicationName"))).get("sessionVarName")


Unnamed ColdFusion Application and Session scopes

If you do not specify an application name in the ColdFusion cfapplication tag, the application is unnamed. ColdFusion supports only a single unnamed application, so if multiple cfapplication tags do not specify an application name, all pages affected by the tags share the single unnamed application Scope. This scope maps directly to the J2EE application scope. Similarly, all sessions of unnamed applications correspond directly to the J2EE application server’s session scope.

You access an Application scope variable from a ColdFusion unnamed application in a JSP page using the following format:

application.getAttribute("applicationVariableName")

You access Session scope variables in a ColdFusion unnamed application as follows:

session.getAttribute("sessionVariableName")

Note: When you use Application and Session variables for the unnamed ColdFusion application in JSP pages and servlets, the variable names must be case-correct. That is, the characters in the variable name must have the same case as you used when you created the variable in ColdFusion. You do not have to use case-correct Application and Session variable names for named ColdFusion applications.


Examples: using JSP with CFML

The following simple examples show how you can integrate JSP pages, servlets, and ColdFusion pages. They also show how you can use the Request, Application, and Session scopes to share data between ColdFusion pages, JSP pages, and servlets.


Calling a JSP page from a CFML page

The following page sets Request, Session, and Application variables and calls a JSP page, passing it a name parameter:

<cfapplication name="myApp" sessionmanagement="yes">
<cfscript>
Request.myVariable = "This";
Session.myVariable = "is a";
Application.myVariable = "test.";
GetPageContext().include("hello.jsp?name=Bobby");
</cfscript>


Reviewing the code

The following table describes the CFML code and its function:

Code
Description
<cfapplication name="myApp"
   sessionmanagement="yes">
Specifies the application name as myApp and enables session management. In most applications, this tag is in the Application.cfm page.
<cfscript>
   Request.myVariable = "This";
   Session.myVariable = "is a";
   Application.myVariable = "test.";
Sets ColdFusion Request, Session, and Application, scope variables. Uses the same name, myVariable, for each variable.
   GetPageContext().include
      ("hello.jsp?name=Bobby");
</cfscript>
Uses the getPageContext function to get the current servlet page context for the ColdFusion page. Uses the include method of the page context object to call the hello.jsp page. Passes the name parameter in the URL.

The hello.jsp page is called by the CFML. It displays the Name parameter in a header and the three variables in the remainder of the body.

<%@page import="java.util.*" %>
<h2>Hello <%= request.getParameter("Name")%>!</h2>

<br>Request.myVariable: <%= request.getAttribute("myvariable")%>
<br>session.myVariable: <%= ((Map)(session.getAttribute("myApp")))
.get("myVariable")%>
<br>Application.myVariable: <%= ((Map)(application.getAttribute("myApp")))
.get("myVariable")%>


Reviewing the code

The following table describes the JSP code and its function:

Code
Description
<%@page import="java.util.*" %>
Imports the java.util package. This contains methods required in the JSP page.
<h2>Hello <%= request.getParameter
   ("name")%>!</h2>
Displays the name passed as a URL parameter from the ColdFusion page. The parameter name is case-sensitive,
<br>request.myVariable: <%= request.
   getAttribute("myvariable")%>
Uses the getAttribute method of the JSP request object to displays the value of the Request scope variable myVariable.
<br>session.myVariable:
<%= ((Map)(session.getAttribute("myApp"))).
get("myVariable")%>
Uses the getAttribute method of the JSP session object to get the myApp object (the Application scope). Casts this to a Java Map object and uses the get method to obtain the myVariable value for display.
<br>Application.myVariable: <%=
((Map)(application.getAttribute("myApp")))
.get("myVariable")%>
Uses the getAttribute method of the JSP myApp application object to obtain the value of myVariable in the Application scope.


Calling a CFML page from a JSP page

The following JSP page sets Request, Session, and Application variables and calls a ColdFusion page, passing it a name parameter:

<%@page import="java.util.*" %>

<% request.setAttribute("myvariable", "This");%>
<% ((Map)session.getAttribute("myApp")).put("myVariable", "is a");%>
<% application.setAttribute("myApp.myvariable", "test.");%>

<jsp:include page="hello.cfm">
    <jsp:param name="name" value="Robert" />
</jsp:include>


Reviewing the code

The following table describes the JSP code and its function:

Code
Description
<%@page import="java.util.*" %>
Imports the java.util package. This contains methods required in the JSP page.
<% request.setAttribute("myvariable",
   "This");%>
Uses the setAttribute method of the JSP request object to set the value of the Request scope variable myVariable.
<% ((Map)session.getAttribute("myApp"))
   .put("myVariable", "is a");%>
Uses the getAttribute method of the JSP session object to get the myApp object (the Application scope). Casts this to a Java Map object and uses the set method to set the myVariable value.
<% application.setAttribute
   ("myApp.myvariable", "test.");%>
Uses the setAttribute method of the JSP application object to set the value of myVariable in the myApp application scope.
<jsp:include page="hello.cfm">
    <jsp:param name="name" value="Robert" />
</jsp:include>
Sets the name parameter to Robert and calls the ColdFusion page hello.cfm.

The following hello.cfm page is called by the JSP page. It displays the Name parameter in a heading and the three variables in the remainder of the body.

<cfapplication name="myApp" sessionmanagement="yes">
<cfoutput>
<h2>Hello #URL.name#!</h2>
Request.myVariable: #Request.myVariable#<br>
Session.myVariable: #Session.myVariable#<br>
Application.myVariable: #Application.myVariable#<br>

</cfoutput>


Reviewing the code

The following table describes the CFML code and its function:

Code
Description
<cfapplication name="myApp"
   sessionmanagement="yes">
Specifies the application name as myApp and enables session management. In most applications, this tag is in the Application.cfm page.
<h2>Hello #URL.name#!</h2>
Displays the name passed using the jsp:param tag on the JSP page. The parameter name is not case-sensitive,
Request.myVariable:
   #Request.myVariable#<br>
Session.myVariable:
   #Session.myVariable#<br>
Application.myVariable:
   #Application.myVariable#<br>
Displays the Request.myVariable, Session. myVariable, and Application.myVariable values.


Using Java objects

You use the cfobject tag to create an instance of a Java object. You use other ColdFusion tags, such as cfset and cfoutput, or CFScript to invoke properties (attributes), and methods (operations) on the object.

Method arguments and return values can be any valid Java type; for example, simple arrays and objects. ColdFusion does the appropriate conversions when strings are passed as arguments, but not when they are received as return values. For more information on type conversion issues, see Java and Cold Fusion Data Type Conversions.

The examples in the following sections assume that the name attribute in the cfobject tag specified the value obj, and that the object has a property called Property, and methods called Method1, Method2, and Method3.

Note: The cfdump tag displays an object’s public methods and data.


Using basic object techniques

The following sections describe how to invoke Java objects.


Invoking objects

The cfobject tag makes Java objects available in ColdFusion. It can access any Java class that is available on the JVM classpath or in either of the following locations:

  • In a Java archive (.jar) file in web_root/WEB-INF/lib
  • In a class (.class) file in web_root/WEB-INF/classes

For example:

<cfobject type="Java" class="MyClass" name="myObj">

Although the cfobject tag loads the class, it does not create an instance object. Only static methods and fields are accessible immediately after the call to cfobject.

If you call a public non-static method on the object without first calling the init method, there ColdFusion makes an implicit call to the default constructor.

To call an object constructor explicitly, use the special ColdFusion init method with the appropriate arguments after you use the cfobject tag; for example:

<cfobject type="Java" class="MyClass" name="myObj">
<cfset ret=myObj.init(arg1, arg2)>

Note: The init method is not a method of the object, but a ColdFusion identifier that calls the new function on the class constructor. So, if a Java object has an init method, a name conflict exists and you cannot call the object’s init method.

To have persistent access to an object, you must use the init function, because it returns a reference to an instance of the object, and cfobject does not.

An object created using cfobject or returned by other objects is implicitly released at the end of the ColdFusion page execution.


Using properties

Use the following coding syntax to access properties if the object does either of the following actions:

  • Exposes the properties as public properties.
  • Does not make the properties public, but is a JavaBean that provides public getter and setter methods of the form getPropertyName() and setPropertyName(value). For more information, see the following Calling JavaBean get and set methods section.

To set a property:

<cfset obj.property = "somevalue">

To get a property:

<cfset value = obj.property>

Note: ColdFusion does not require that property and method names be case-correct. However, you should use the same case in ColdFusion as you do in Java to ensure consistency.


Calling methods

Object methods usually take zero or more arguments. Some methods return values, while others may not. Use the following techniques to call methods:

  • If the method has no arguments, follow the method name with empty parentheses, as in the following cfset tag.
    • <cfset retVal = obj.Method1()>
  • If the method has one or more arguments, put the arguments in parentheses, separated by commas, as in the following example, which has one integer argument and one string argument.
    • <cfset x = 23>
<cfset retVal = obj.Method1(x, "a string literal")>

Note: When you invoke a Java method, the type of the data being used is important. For more information see Java and Cold Fusion Data Type Conversions.


Calling JavaBean get and set methods

ColdFusion can automatically invoke getPropertyName() and setPropertyName(value) methods if a Java class conforms to the JavaBeans pattern. As a result, you can set or get the property by referencing it directly, without having to explicitly invoke a method.

For example, if the myFishTank class is a JavaBean, the following code returns the results of calling the getTotalFish() method on the myFish object:

<cfoutput>
   There are currently #myFish.TotalFish# fish in the tank.
</cfoutput>

The following example adds one guppy to a myFish object by implicitly calling the setGuppyCount(int number) method:

<cfset myFish.GuppyCount = myFish.GuppyCount + 1>

Note: You can use the direct reference method to get or set values in some classes that have getProperty and setProperty methods but do not conform fully to the JavaBean pattern. However, you cannot use this technique for all classes that have getProperty and setProperty methods. For example, you cannot directly reference any of the following standard Java classes, or classes derived from them: Date, Boolean, Short, Integer, Long, Float, Double, Char, Byte, String, List, Array.


Calling nested objects

ColdFusion supports nested (scoped) object calls. For example, if an object method returns another object and you must invoke a property or method on that object, you can use the following syntax:

<cfset prop = myObj.X.Property>.

Similarly, you can use code such as the following CFScript line:

GetPageContext().include("hello.jsp?name=Bobby");

In this code, the ColdFusion GetPageContext function returns a Java PageContext object, and the line invokes the PageContext object’s include method.


Creating and using a simple Java class

Java is a strongly typed language, unlike ColdFusion, which does not enforce data types. As a result, there are some subtle considerations when calling Java methods. The following sections create and use a Java class to show how to use Java effectively in ColdFusion pages.


The Employee class

The Employee class has four data members: FirstName and LastName are public, and Salary and JobGrade are private. The Employee class has three overloaded constructors and a overloaded SetJobGrade method.

Save the following Java source code in the file Employee.java, compile it, and place the resulting Employee.class file in a directory that is specified in the classpath.

public class Employee {

public String FirstName;
public String LastName;
private float Salary;
private int   JobGrade;

public void Employee() {
  FirstName ="";
  LastName ="";
  Salary   = 0.0f;
  JobGrade = 0;
}

public void Employee(String First, String Last) {
  FirstName = First;
  LastName = Last;
  Salary   = 0.0f;
  JobGrade = 0;
}

public void Employee(String First, String Last, float salary, int grade) {
  FirstName = First;
  LastName = Last;
  Salary   = salary;
  JobGrade = grade;
}

public void SetSalary(float Dollars) {
   Salary = Dollars;
}

public float GetSalary() {
  return Salary;
}

public void SetJobGrade(int grade) {
  JobGrade = grade;
}

public void SetJobGrade(String Grade) {
  if (Grade.equals("CEO")) {
    JobGrade = 3;
  }
  else if (Grade.equals("MANAGER")) {
    JobGrade = 2;
  }
  else if (Grade.equals("DEVELOPER")) {
    JobGrade = 1;
  }
}

public int GetJobGrade() {
  return JobGrade;
}

}


A CFML page that uses the Employee class

Save the following text as JEmployee.cfm:

<html>
<body>
<cfobject action="create" type="java" class="Employee" name="emp">
<!--- <cfset emp.init()> --->
<cfset emp.firstname="john">
<cfset emp.lastname="doe">
<cfset firstname=emp.firstname>
<cfset lastname=emp.lastname>
</body>

<cfoutput>
   Employee name is  #firstname# #lastname#
</cfoutput>
</html>

When you view the page in your browser, you get the following output:

Employee name is john doe


Reviewing the code

The following table describes the CFML code and its function:

Code
Description
<cfobject action=create
   type=java class=Employee
   name=emp>
Loads the Employee Java class and gives it an object name of emp.
<!--- <cfset emp.init()> --->
Does not call a constructor. ColdFusion invokes the default constructor when it first uses the class; in this case, when it processes the next line.
<cfset emp.firstname="john">
<cfset emp.lastname="doe">
Sets the public fields in the emp object to your values.
<cfset firstname=emp.firstname>
<cfset lastname=emp.lastname>
Gets the field values back from emp object.
<cfoutput>
   Employee name is #firstname#
      #lastname#
</cfoutput>
Displays the retrieved values.


Java considerations

Keep the following points in mind when you write a ColdFusion page that uses a Java class object:

  • The Java class name is case sensitive. You must ensure that the Java code and the CFML code use Employee as the class name.
  • Although Java method and field names are case sensitive, ColdFusion variables are not case sensitive, and ColdFusion does any necessary case conversions. As a result, the sample code works even though the CFML uses emp.firstname and emp.lastname; the Java source code uses FirstName and LastName for these fields.
  • If you do not call the constructor (or, as in this example, comment it out), ColdFusion automatically invokes the default constructor when it first uses the class.


Using an alternate constructor

The following CFML page explicitly calls one of the alternate constructors for the Employee object:

<html>
<body>

<cfobject action="create" type="java" class="Employee" name="emp">
<cfset emp.init("John", "Doe", 100000.00, 10 )>
<cfset firstname=emp.firstname>
<cfset lastname=emp.lastname>
<cfset salary=emp.GetSalary()>
<cfset grade=emp.GetJobGrade()>

<cfoutput>
   Employee name is  #firstname# #lastname#<br>
   Employee salary #DollarFormat(Salary)#<br>
   Employee Job Grade  #grade#
</cfoutput>

</body>
</html>

In this example, the constructor takes four arguments: the first two are strings, the third is a float, and the fourth is an integer.


Java and Cold Fusion Data Type Conversions

Cold Fusion does not use explicit types for variables, while Java is strongly typed. However, ColdFusion data does use a number of underlying types to represent data.

Under most situations, when the method names are not ambiguous, ColdFusion can determine the data types that are required by a Java object, and often it can convert ColdFusion data to the required types. For example, ColdFusion text strings are implicitly converted to the Java String type. Similarly, if a Java object contains a doIt method that expects a parameter of type int, and CFML is issuing a doIt call with a CFML variable x that contains an integer value, ColdFusion converts the variable x to Java int type. However, ambiguous situations can result from Java method overloading, where a class has multiple implementations of the same method that differ only in their parameter types.

The following sections describe how ColdFusion handles the unambiguous situations, and how it provides you with the tools to handle ambiguous ones.


Default data type conversion

Whenever possible, ColdFusion automatically matches Java types to ColdFusion types.

The following table lists how ColdFusion converts ColdFusion data values to Java data types when passing arguments. The left column represents the underlying ColdFusion representation of its data. The right column indicates the Java data types into which ColdFusion can automatically convert the data:

CFML
Java
Integer
short, int, long (short and int might result in a loss of precision)
Real number
float double (float might result in a loss of precision.
Boolean
boolean
Date-time
java.util.Date
String, including lists
String
short, int, long, float, double, java.util.Date, when a CFML string represents a number or date
boolean, for strings with the value "Yes", "No", "True", and "False" (case-insensitive)
Array
java.util.Vector (ColdFusion Arrays are internally represented using an instance of a java.util.Vector object.)
ColdFusion can also map a CFML array to any of the following when the CFML array contains consistent data of a type that can be converted to the Java array’s data type: byte[], char[], boolean[], int[], long[], float[], double[], String[], or Object[]. When a CFML array contains data of different of types, the conversion to a simple array type might fail.
Structure
java.util.Map
Query object
java.util.Map
XML document object
Not supported
ColdFusion component
N/A

The following table lists how ColdFusion converts data returned by Java methods to ColdFusion data types:

Java | CFML
boolean/Boolean | Boolean
byte/Byte | String
char/Char | String
short/Short | Integer
int/Integer | Integer
long/Long | Integer
float/Float | Real Number
double/Double | Real Number
String | String
java.util.Date | Date-time
java.util.List | Comma delimited List
byte[] | Array
char[] | Array
boolean[] | Array
String[] | Array
java.util.Vector | Array
java.util.Map | Structure


Resolving ambiguous data types with the JavaCast function

You can overload Java methods so a class can have several identically named methods. At runtime, the JVM resolves the specific method to use based on the parameters passed in the call and their types.

In the section , the Employee class has two implementations for the SetJobGrade method. One method takes a string variable, the other an integer. If you write code such as the following, which implementation to use is ambiguous:

<cfset  emp.SetJobGrade(“1”)>

The “1” could be interpreted as a string or as a number, so there is no way to know which method implementation to use. When ColdFusion encounters such an ambiguity, it throws a user exception.

The ColdFusion JavaCast function helps you resolve such issues by specifying the Java type of a variable, as in the following line:

<cfset  emp.SetJobGrade(JavaCast(“int”, “1”))>

The JavaCast function takes two parameters: a string representing the Java data, and the variable whose type you are setting. You can specify the following Java data types: boolean, int, long, float, double, and String.

For more information on the JavaCast function, see the CFML Reference.


Handling Java exceptions

You handle Java exceptions just as you handle standard ColdFusion exceptions, with the cftry and cfcatch tags. You specify the name of the exception class in the cfcatch tag that handles the exception. For example, if a Java object throws an exception named myException, you specify myException in the cfcatch tag

Note: To catch any exception generated by a Java object, specify java.lang.Exception for the cfcatch type attribute. To catch any Throwable errors, specify java.lang.Throwable in the cfcatch tag type attribute.

The following sections show an example of throwing and handling a Java exception.

For more information on exception handling in ColdFusion, see Handling Errors.


Example: exception-throwing class

The following Java code defines the testException class that throws a sample exception. It also defines a myException class that extends the Java built-in Exception class and includes a method for getting an error message.

The myException class has the following code. It throws an exception with a message that is passed to it, or if no argument is passed, it throws a canned exception.

//class myException
public class myException extends Exception
{
   public myException(String msg) {
      super(msg);
   }
   public myException() {
      super("Error Message from myException");
   }
}

The testException class contains one method, doException, which throws a myException error with an error message.

public class testException {
   public testException ()
   {
   }
   public void doException() throws myException {
        throw new myException("Throwing an exception from testException class");
    }
}


Example: CFML Java exception handling code

The following CFML code calls the testException class doException method. The cfcatch block handles the resulting exception.

<cfobject action=create type=java class=testException name=Obj>
<cftry>
   <cfset Obj.doException() >
   <cfcatch type="myException">
      <cfoutput>
         <br>The exception message is: #cfcatch.Message#<br>
      </cfoutput>
   </cfcatch>
</cftry>


Examples: using Java with CFML

The following sections show several examples of using Java objects in CFML. They include examples of using a custom Java class, a standard Java API class in a user-defined function, a JavaBean, and an Enterprise JavaBean (EJB).


Using a Java API in a UDF

The following example of a user defined function (UDF) is functionally identical to the GetHostAddress function from the NetLib library of UDFs from the Common Function Library Project, http://www.cflib.org. It uses the InetAddress class from the standard Java 2 java.net package to get the Internet address of a specified host:

function GetHostAddress(host) {
   // Define the function local variables.
   var iaddrClass="";
   var address="";

   // Initialize the Java class.
   iaddrClass=CreateObject("java", "java.net.InetAddress");

   // Get the address object.
   address=iaddrClass.getByName(host);

   // Return the address
   return address.getHostAddress();
}


Using an EJB

ColdFusion can use EJBs that are served by JRun 4.0 servers. The JRun Server Jrun.jar file must have the same version as the Jrun.jar file in ColdFusion.

To call an EJB, you use cfobject type="Java" to create and call the appropriate objects. Before you can use an EJB you must do the following:

  • Have a properly deployed EJB running on a J2EE server. The bean must be registered with the JNDI server.
  • Have the following information:
    • Name of the EJB server
    • Port number of the JNDI naming service on the EJB server
    • Name of the EJB, as registered with the naming service
  • Install the EJB home and component interface compiled classes on your ColdFusion web server, either as class files in the web_root\WEB-INF\classes directory or packaged in a JAR file the web_root\WEB-INF\lib directory.

Note: To use an EJB served by a JRUN server, your ColdFusion installation and the JRun server that hosts the EJB must have the same version of the jrun.jar file (located in cf_root\runtime\lib directory in ColdFusion).

While the specific steps for using an EJB depend on the EJB server and on the EJB itself, they generally correspond to the following outline:

To use an EJB

  1. Use the cfobject tag to create an object of the JNDI naming context class (javax.naming.Context). You will use fields from this class to define the information that you use to locate the EJB. Because you only use fields, you do not initialize the object.
  2. Use the cfobject tag to create a java.util.Properties class object that will contain the context object properties.
  3. Call the init method to initialize the Properties object.
  4. Set the Properties object to contain the properties that are required to create an initial JNDI naming context. These include the INITIAL_CONTEXT_FACTORY and PROVIDER_URL properties. You might also need to provide SECURITY_PRINCIPAL and SECURITY_CREDENTIALS values required for secure access to the naming context. For more information on these properties, see the JNDI documentation.
  5. Use the cfobject tag to create the JNDI InitialContext (javax.naming. InitialContext) object.
  6. Call the init method for the InitialContext object with the Properties object values to initialize the object.
  7. Call the InitialContextext object’s lookup method to get a reference to the home interface for the bean that you want. Specify the JNDI name of the bean as the lookup argument.
  8. Call the create method of the bean’s home object to create a new instance of the bean. If you are using Entity beans, you typically use a finder method instead. A finder method locates one or more existing entity beans.
  9. Now you can use the bean’s methods as required by your application.
  10. When finished, call the context object’s close method to close the object.

The following code shows this process using a simple Java Entity bean on a JRun 4.0 server. It calls the bean’s getMessage method to obtain a message.

<html>
<head>
  <title>cfobject Test</title>
</head>

<body>
<H1>cfobject Test</H1>
<!--- Create the Context object to get at the static fields. --->
<CFOBJECT
  action=create
  name=ctx
  type="JAVA"
  class="javax.naming.Context">

<!--- Create the Properties object and call an explicit constructor--->
<CFOBJECT
  action=create
  name=prop
  type="JAVA"
  class="java.util.Properties">

<!--- Call the init method (provided by cfobject)
      to invoke the Properties object constructor. --->
<cfset prop.init()>

<!--- Specify the properties These are required for a remote server only --->
<cfset prop.put(ctx.INITIAL_CONTEXT_FACTORY, "jrun.naming.JRunContextFactory")>
<cfset prop.put(ctx.PROVIDER_URL, "localhost:2908")>
<!--- <cfset prop.put(ctx.SECURITY_PRINCIPAL, "admin")>
      <cfset prop.put(ctx.SECURITY_CREDENTIALS, "admin")>
 --->
<!--- Create the InitialContext  --->
<CFOBJECT
  action=create
  name=initContext
  type="JAVA"
  class="javax.naming.InitialContext">

<!--- Call the init method (provided through cfobject)
      to pass the properties to the InitialContext constructor. --->
<cfset initContext.init(prop)>

<!--- Get reference to home object. --->
<cfset home = initContext.lookup("SimpleBean")>

<!--- Create new instance of entity bean.
      (hard-wired account number). Alternatively,
      you would use a find method to locate an
      existing entity bean. --->
<cfset mySimple = home.create()>

<!--- Call a method in the entity bean. --->
<cfset myMessage = mySimple.getMessage()>

<cfoutput>
   #myMessage#<br>
</cfoutput>

<!--- Close the context. --->
<cfset initContext.close()>

</body>
</html>


Using a custom Java class

The following code provides a more complex custom class than in the example Creating and using a simple Java class. The Example class manipulates integer, float, array, Boolean, and Example object types.


The Example class

The following Java code defines the Example class. The Java class Example has one public integer member, mPublicInt. Its constructor initializes mPublicInt to 0 or an integer argument. The class has the following public methods:

Method | Description
ReverseString | Reverses the order of a string.
ReverseStringArray | Reverses the order of elements in an array of strings.
Add | Overloaded: Adds and returns two integers or floats or adds the mPublicInt members of two Example class objects and returns an Example class object.
SumArray | Returns the sum of the elements in an integer array.
SumObjArray | Adds the values of the mPublicInt members of an array of Example class objects and returns an Example class object.
ReverseArray | Reverses the order of an array of integers.
Flip | Switches a Boolean value.

public class Example {
  public   int      mPublicInt;

  public Example() {
      mPublicInt = 0;
  }

  public Example(int IntVal) {
      mPublicInt = IntVal;
  }

  public String ReverseString(String s) {
      StringBuffer buffer = new StringBuffer(s);
      return new String(buffer.reverse());
  }

  public String[] ReverseStringArray(String [] arr) {
    String[] ret = new String[arr.length];
    for (int i=0; i < arr.length; i++) {
      ret[arr.length-i-1]=arr[i];
    }
    return ret;
  }

  public int Add(int a, int b) {
      return (a+b);
  }

  public float Add(float a, float b) {
      return (a+b);
  }

  public Example Add(Example a, Example b) {
      return new Example(a.mPublicInt + b.mPublicInt);
  }

 static  public int SumArray(int[] arr) {
    int sum=0;
    for (int i=0; i < arr.length; i++) {
      sum += arr[i];
    }
    return sum;
  }

  static  public Example SumObjArray(Example[] arr) {
    Example sum= new Example();
    for (int i=0; i < arr.length; i++) {
      sum.mPublicInt += arr[i].mPublicInt;
    }
    return sum;
  }

  static public int[] ReverseArray(int[] arr) {
    int[] ret = new int[arr.length];
    for (int i=0; i < arr.length; i++) {
      ret[arr.length-i-1]=arr[i];
    }
    return ret;
  }

  static public boolean Flip(boolean val) {
      System.out.println("calling flipboolean");
      return val?false:true;
  }
}


The useExample CFML page

The following useExample.cfm page uses the Example class to manipulate numbers, strings, Booleans, and Example objects. The JavaCast CFML function ensures that CFML variables convert into the appropriate Java data types.

<html>
<head>
   <title>CFOBJECT and Java Example</title>
</head>
<body>

<!--- Create a reference to an Example object --->
<cfobject action=create type=java class=Example name=obj>
<!--- Create the object and initialize its public member to 5 --->
<cfset x=obj.init(JavaCast("int",5))>

<!--- Create an array and populate it with string values,
      then use the Java object to reverse them. --->
<cfset myarray=ArrayNew(1)>
<cfset myarray[1]="First">
<cfset myarray[2]="Second">
<cfset myarray[3]="Third">
<cfset ra=obj.ReverseStringArray(myarray)>

<!--- Display the results --->
<cfoutput>
   <br>
   original array element 1: #myarray[1]#<br>
   original array element 2: #myarray[2]#<br>
   original array element 3: #myarray[3]#<br>
   after reverse  element 1: #ra[1]#<br>
   after reverse  element 2: #ra[2]#<br>
   after reverse  element 3: #ra[3]#<br>
   <br>
</cfoutput>

<!--- Use the Java object to flip a Boolean value, reverse a string,
      add two integers, and add two float numbers --->
<cfset c=obj.Flip(true)>
<cfset StringVal=obj.ReverseString("This is a test")>
<cfset IntVal=obj.Add(JavaCast("int",20),JavaCast("int",30))>
<cfset FloatVal=obj.Add(JavaCast("float",2.56),JavaCast("float",3.51))>

<!--- Display the results --->
<cfoutput>
   <br>
   StringVal: #StringVal#<br>
   IntVal: #IntVal#<br>
   FloatVal: #FloatVal#<br>
   <br>
</cfoutput>

<!--- Create a two-element array, sum its values,
      and reverse its elements --->
<cfset intarray=ArrayNew(1)>
<cfset intarray[1]=1>
<cfset intarray[2]=2>
<cfset IntVal=obj.sumarray(intarray)>
<cfset reversedarray=obj.ReverseArray(intarray)>

<!--- Display the results --->
<cfoutput>
   <br>
   IntVal1 :#IntVal#<br>
   array1: #reversedarray[1]#<br>
   array2: #reversedarray[2]#<br>
   <br>
</cfoutput><br>

<!--- Create a ColdFusion array containing two Example objects.
      Use the SumObjArray method to add the objects in the array
      Get the public member of the resulting object--->
<cfset oa=ArrayNew(1)>
<cfobject action=create type=java class=Example name=obj1>
<cfset VOID=obj1.init(JavaCast("int",5))>
<cfobject action=create type=java class=Example name=obj2>
<cfset VOID=obj2.init(JavaCast("int",10))>
<cfset oa[1] = obj1>
<cfset oa[2] = obj2>
<cfset result = obj.SumObjArray(oa)>
<cfset intval = result.mPublicInt>

<!--- Display the results --->
<cfoutput>
   <br>
   intval1: #intval#<br>
   <br>
</cfoutput><br>
</body>
</html>

Previous


Integrating COM and CORBA Objects in CFML Applications

This chapter describes how to use the cfobject tag to invoke COM (Component Object Model) or DCOM (Distributed Component Object Model) and CORBA (Common Object Request Broker) objects.

Contents
  • About COM and CORBA
  • Creating and using objects
  • Getting started with COM and DCOM
  • Creating and using COM objects
  • Getting started with CORBA
  • Creating and using CORBA objects
  • CORBA Example
Next


About COM and CORBA

This section provides some basic information on COM and CORBA objects supported in ColdFusion and provides resources for further inquiry.


About objects

COM and CORBA are two of the object technologies supported by ColdFusion. Other object technologies include Java and ColdFusion components. For more information on Java, see Integrating COM and CORBA Objects in CFML Applications. For more information on ColdFusion components see Building and Using ColdFusion Components.

An object is a self-contained module of data and its associated processing. An object is a building block that you can put together with other objects and integrate into ColdFusion code to create an application.

An object is represented by a handle, or name. Objects have properties that represent information. Objects also provide methods for manipulating the object and getting data from it. The exact terms and rules for using objects vary with the object technology.

You create instances of objects using the cfobject tag or the CreateObject function. You then use the object and its methods in ColdFusion tags, functions, and expressions. For more information on the ColdFusion syntax for using objects, see Creating and using objects


About COM and DCOM

COM (Component Object Model) is a specification and a set of services defined by Microsoft to enable component portability, reusability, and versioning. DCOM (Distributed Component Object Model) is an implementation of COM for distributed services, which allows access to components residing on a network.

COM objects can reside locally or on any network node. COM is supported on Microsoft Windows platforms.

For more information on COM, go to the Microsoft COM website, .


About CORBA

CORBA (Common Object Request Broker Architecture) is a distributed computing model for object-oriented applications defined by the Object Management Group (OMG). In this model, an object is an encapsulated entity whose services are accessed only through well-defined interfaces. The location and implementation of each object is hidden from the client requesting the services. ColdFusion supports CORBA 2.3 on both Windows and UNIX.

CORBA uses an Object Request Broker (ORB) to send requests from applications on one system to objects executing on another system. The ORB allows applications to interact in a distributed environment, independent of the computer platforms on which they run and the languages in which they are implemented. For example, a ColdFusion application running on one system can communicate with an object that is implemented in C++ on another system.

CORBA follows a client-server model. The client invokes operations on objects that are managed by the server, and the server replies to requests. The ORB manages the communications between the client and the server using the Internet Inter-ORB Protocol (IIOP).

Each CORBA object has an interface that is defined in the CORBA Interface Definition Language (IDL). The CORBA IDL describes the operations that can be performed on the object, and the parameters of those operations. Clients do not have to know anything about how the interface is implemented to make requests.

To request a service from the server, the client application gets a handle to the object from the ORB. It uses the handle to call the methods specified by the IDL interface definition. The ORB passes the requests to the server, which processes the requests and returns the results to the client.

For information about CORBA, see the following OMG website, which is the main Web repository for CORBA information:


Creating and using objects

You use the cfobject tag or the CreateObject function to create a named instance of an object. You use other ColdFusion tags, such as cfset and cfoutput, to invoke the object’s properties and methods.

The following sections provide information about creating and using objects that applies to both COM and CORBA objects. The examples assume a sample object named “obj”, and that the object has a property called “Property”, and methods called “Method1”, “Method2”, and “Method3”.


Creating objects

You create, or instantiate (create a named instance of) an object in ColdFusion with the cfobject tag or CreateObject function. The specific attributes or parameters that you use depend on the type of object you use, and are described in detail in Creating and using COM objects and Creating CORBA objects. The following examples use a cfobject tag to create a COM object and a CreateObject function to create a CORBA object:

<cfobject type="COM" action="Create" name="obj" class="sample.MyObject">
obj = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "Visibroker")

ColdFusion releases any object created by cfobject or CreateObject, or returned by other objects, at the end of the ColdFusion page execution.


Using properties

Use standard ColdFusion statements to access properties.

  • To set a property, use a statement or cfset tag such as the following:
    • <cfset obj.property = "somevalue">
  • To get a property, use a statement or cfset tag such as the following:
    • <cfset value = obj.property>

Note that, as shown in this example, you do not use parentheses on the right side of the equation to get a property value.


Calling methods

Object methods usually take zero or more arguments. You send In arguments, whose values are not returned to the caller by value. You send Out and In,Out arguments, whose values are returned to the caller, by reference. Arguments sent by reference usually have their value changed by the object. Some methods have return values, while others may not.

Use the following techniques call methods:

  • If the method has no arguments, follow the method name with empty parentheses, as in the following cfset tag.
    • <cfset retVal = obj.Method1()>
  • If the method has one or more arguments, put the arguments in parentheses, separated by commas, as in the following example, which has one integer argument and one string argument.
    • <cfset x = 23>
<cfset retVal = obj.Method1(x, "a string literal")>
  • If the method has reference (Out or In,Out arguments) use double quotation marks (") around the name of the variable you are using for these arguments, as shown for the variable x in the following example:
    • <cfset x = 23>
<cfset retVal = obj.Method2("x",  "a string literal")>
<cfoutput> #x#</cfoutput>

In this example, if the object changes the value of x, it now contains a value other than 23.


Calling nested objects

ColdFusion supports nested (scoped) object calls. For example, if an object method returns another object, and you must invoke a property or method on that object, you can use the syntax in either of the following examples:

<cfset prop = myObj.X.Property>

or

<cfset objX = myObj.X>
<cfset prop = objX.Property>


Getting started with COM and DCOM

ColdFusion is an automation (late-binding) COM client. As a result, the COM object must support the IDispatch interface, and arguments for methods and properties must be standard automation types. Because ColdFusion is a typeless language, it uses the object's type information to correctly set up the arguments on call invocations. Any ambiguity in the object's data types can lead to unexpected behavior.

In ColdFusion, you should only use server-side COM objects, which do not have a graphical user interface. If your ColdFusion application invokes an object with a graphical interface in a window, the component might appear on the web server desktop, not on the user's desktop. This can take up ColdFusion Server threads and prevent further Web server requests from being serviced.

ColdFusion can call Inproc, Local, or Remote COM objects. The attributes specified in the cfobject tag determine which type of object is called.


COM Requirements

To use COM components in your ColdFusion application, you need at least the following items:

  • The COM objects (typically DLL or EXE files) that you want to use in your ColdFusion application pages. These components should allow late binding; that is, they should implement the IDispatch interface.
  • Microsoft OLE/COM Object Viewer, available from Microsoft at
    . This tool let you view registered COM objects.

    • Object Viewer lets you view an object's class information so that you can properly define the class attribute for the cfobject tag. It also displays the object's supported interfaces, so you can discover the properties and methods (for the IDispatch interface) of the object.


Registering the object

After you acquire an object, you must register it with Windows for ColdFusion (or any other program) to find it. Some objects have setup programs that register objects automatically, while others require manual registration.

You can register Inproc object servers (.dll or .ocx files) manually by running the regsvr32.exe utility using the following form:

regsvr32 c:\path\servername.dll

You typically register Local servers (.exe files) either by starting them or by specifying a command line parameters, such as the following:

C:\pathname\servername.exe -register


Finding the component ProgID and methods

Your COM object supplier should provide documentation that explains each of the component's methods and the ProgID. If you do not have documentation, use the OLE/COM Object Viewer to view the component's interface.


Using the OLE/COM Object Viewer

The OLE/COM Object Viewer installation installs the executable, by default, as \mstools\bin\oleview.exe. You use the Object Viewer to retrieve a COM object's Program ID, as well as its methods and properties.

To find an object in the Object Viewer, it must be registered, as described in Registering the object. The Object Viewer retrieves all COM objects and controls from the Registry, and presents the information in a simple format, sorted into groups for easy viewing.

By selecting the category and then the component, you can see the Program ID of a COM object. The Object Viewer also provides access to options for the operation of the object.

To view an object's properties:

  1. Open the Object Viewer, as shown in the following figure, and scroll to the object you want to examine.

    2. This is a picture of the feature being described.

  2. Select and expand the object in the left pane of the Object Viewer.
  3. Right-click the object to view it, including the TypeInfo.

    4. If you view the TypeInfo, you see the object's methods and properties, as shown in the following figure. Some objects do not have access to the TypeInfo area, which is determined when an object is built and by the language used.

This is a picture of the feature being described.


Creating and using COM objects

You must use the cfobject tag or the CreateObject function to create an instance of the COM object (component) in ColdFusion before your application pages can invoke any methods or assign any properties in the component.

For example, the following code uses the cfobject tag to create the Windows CDO (Collaborative Data Objects) for NTS NewMail object to send mail:

<cfobject type="COM"
      action="Create"
      name="Mailer"
      class="CDONTS.NewMail">

The following line shows how to use the corresponding CreateObject function in CFScript:

Mailer = CreateObject("COM", "CDONTS.NewMail");

The examples in later sections in this chapter use this object.

Note: CDO is installed by default on all Windows NT and 2000 operating systems that have installed the Microsoft SMTP server. In Windows NT Server environments, the SMTP server is part of the Option Pack 4 setup. In Windows 2000 Server and Workstation environments, it is bundled with the operating system. For more information on CDO for NTS, see http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/cdo/_olemsg_overview_of_cdo.htm.

The CDO for NTS NewMail component includes a number of methods and properties to perform a wide range of mail-handling tasks. (In the OLE/COM Object Viewer, methods and properties might be grouped together, so you could find it difficult to distinguish between them at first.)

The CDO for NTS NewMail object includes the following properties:

Body [ String ]
Cc  [ String ]
From  [ String ]
Importance  [ Long ]
Subject  [ String ]
To  [ String ]

You use these properties to define elements of your mail message. The CDO for NTS NewMail object also includes a send method which has a number of optional arguments to send messages.


Connecting to COM objects

The action attribute of the cfobject tag provides the following two ways to connect to COM objects:

  • Create method (cfobject action="Create") Takes a COM object, typically a DLL, and instantiates it prior to invoking methods and assigning properties.
  • Connect method (cfobject action="Connect") Links to an object, typically an executable, that is already running on the server.

You can use the optional cfobject context attribute to specify the object context. If you do not specify a context, ColdFusion uses the setting in the Registry. The following table describes the context attribute values:

Attribute value | Description
InProc | An in-process server object (typically a DLL) that is running in the same process space as the calling process, such as ColdFusion.
local | An out-of-process server object (typically an EXE file) that is running outside the ColdFusion process space but running locally on the same server.
remote | An out-of-process server object (typically an EXE file) that is running remotely on the network. If you specify remote, you must also use the server attribute to identify where the object resides.


Setting properties and invoking methods

The following example, which uses the sample Mailer COM object, shows how to assign properties to your mail message and how to execute component methods to handle mail messages.

In the example, form variables contain the method parameters and properties, such as the name of the recipient, the desired e-mail address, and so on.

<!--- First, create the object --->
<cfobject type="COM"
   action="Create"
   name="Mailer"
   class="CDONTS.NewMail">

<!--- Second, use the form variables from the user entry form to populate a number
      of properties necessary to create and send the message. --->
<cfset Mailer.From = "#Form.fromName#">
<cfset Mailer.To = "#Form.to#">
<cfset Mailer.Subject = "#Form.subject#">
<cfset Mailer.Importance = 2>
<cfset Mailer.Body = "#Form.body#">
<cfset Mailer.Cc = "#Form.cc#">

<!--- Last, use the Send() method to send the message.
   Invoking the Send() method destroys the object.--->
<cfset Mailer.Send()>

Note: Use the cftry and cfcatch tags to handle exceptions thrown by COM objects. For more information on exception handling, see Handling Run-time Exceptions with ColdFusion Tags.


COM object considerations

When you use COM objects, consider the following to prevent and resolve errors:

  • Ensure correct threading
  • Use input and output arguments correctly
  • Understand common COM-related error messages.

The following sections describe these issues.


Ensuring correct threading

Improper threading can cause serious problems when using a COM object in ColdFusion. Make sure that the object is thread-safe. An object is thread-safe if it can be called from many programming threads simultaneously, without causing errors.

Visual Basic ActiveX DLLs are typically not thread-safe. If you use such a DLL in ColdFusion, you can make it thread-safe by using the OLE/COM Object Viewer to change the object’s threading model to the Apartment model.

If you are planning to store a reference to the COM object in the Application, Session, or Server scope, do not use the Apartment threading model. This threading model is intended to service only a single request. If your application requires you to store the object in any of these scopes, keep the object in the Both threading model, and lock all code that accesses the object, as described in Locking code with cflock.

To change the threading model of a COM Object:

  1. Open the OLE/COM Object Viewer.
  2. Select All Objects under Object Classes in the left pane.
  3. Locate your COM object. The left pane lists these by name.
  4. Select your object.
  5. Select the Implementation tab in the right pane.
  6. Select the Inproc Server tab, below the App ID field.
  7. Select the Threading Model drop down menu and select Apartment or Both, as appropriate.


Using input and output arguments

COM object method in arguments are passed by value. The COM object gets a copy of the variable value, so you can specify a ColdFusion variable without surrounding it with quotation marks.

COM object out method arguments are passed by reference. The COM object modifies the contents of the variable on the calling page, so the calling page can use the resulting value. To pass a variable by reference, surround the name of an existing ColdFusion variable with quotation marks. If the argument is a numeric type, assign the variable a valid number before you make the call.

For example:

<cfset inStringArg="Hello Object">
<cfset outNumericArg=0>
<cfset result=myCOMObject.calculate(inStringArg, "outNumericArg")>

The string "Hello Object" is passed to the object's calculate method as an input argument. The value of outNumericArg is set by the method to a numeric value.


Understanding common COM-related error messages

The following table described some error messages you might encounter when using COM objects:

Error
Cause
Error Diagnostic Information
Error trying to create object specified in the tag.
COM error 0x800401F3. Invalid class string
The COM object is not registered or does not exist.
Error Diagnostic Information
Error trying to create object specified in the tag.
COM error 0x80040154. Class not registered
The COM object is not registered or does not exist. This error usually occurs when an object existed previously, but was uninstalled.
Error Diagnostic Information
Failed attempting to find "SOMEMETHOD"
property/method on the object COM error 0x80020006.
Unknown name.
The COM object was instantiated correctly, but the method you specified does not exist.


Getting started with CORBA

The ColdFusion cfobject tag and CreateObject function support CORBA through the Dynamic Invocation Interface (DII). As with COM, the object's type information must be available to ColdFusion. Therefore, an IIOP-compliant Interface Repository (IR) must be running on the network, and the object's Interface Definition Language (IDL) specification must be registered in the IR. If your application uses a naming service to get references to CORBA objects, a naming service must also be running on the network.

ColdFusion loads ORB runtime libraries at startup using a connector, which does not tie ColdFusion customers to a specific ORB vendor. ColdFusion currently includes connectors for the Borland Visibroker 4.5 ORB. The source necessary to write connectors for other ORBs is available under NDA to select third-party candidates and ORB vendors

You must take several steps to configure and enable CORBA access in ColdFusion. For detailed instructions, see Installing ColdFusion MX.

Note: When you enable CORBA access in ColdFusion, one step requires you to start the Interface Repository using an IDL file. This file must contain the IDL for all the CORBA objects that you invoke in ColdFusion applications on the server. Additionally, If you


Creating and using CORBA objects

The following sections describe how to create, or instantiate, a CORBA object and how to use it in your ColdFusion application.


Creating CORBA objects

The cfobject tag and CreateObject functions create in ColdFusion a stub, or proxy object, for the CORBA object on the remote server. You use this stub object to invoke the remote object.

The following table describe the attributes you use in the cfobject tag to create a CORBA object.

Attribute
Description
type
Must be CORBA. COM is the default.
context
Specifies the CORBA binding method, that is, how the object is obtained, as follows:
  • IOR Uses a file containing the object's unique Interoperable Object Reference.
  • NameService Uses a naming service.
class
Specifies the information required for the binding method to access the object.
If you set the context attribute to IOR, The class attribute must be to the full pathname of a file containing the string version of the IOR. ColdFusion must be able to read this IOR file at all times, so make it local to the server or put it on the network in an accessible location.
If you set the context attribute to NameService, The class attribute must be a name delimited by forward slashes (/), such as MyCompany/Department/Dev. You can use period-delimited “kind” identifiers as part of the class attribute; for example, Macromedia.current/Eng.current/CF"
name
Specifies the name (handle) that your application uses to call the object's interface.
locale
(Optional) Identifies the connector configuration. You can omit this option if ColdFusion Administrator has only one connector configuration, or if it has multiple connector configurations and you want to use the one that is currently selected in the Administrator. If you specify this attribute, it must be an ORB name you specified in the CORBA Connector ORB Name field when you configured a CORBA connector in ColdFusion Administrator; for example, Visibroker.

For example, use the following CFML to invoke a CORBA object specified by the tester.ior file if you configured your ORB name as Visibroker:

<cfobject  action = "create" type = "CORBA" context = "IOR"
class = "d:\temp\tester.ior" name = "handle" locale = "Visibroker">

When you use the CreateObject function to invoke this CORBA object, specify the name as the function return variable, and specify the type, class, context, and locale as arguments. For example, the following line creates the same object as the preceding cfobject tag:

handle = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "Visibroker")

For the complete cfobject and CreatObject syntax, see the CFML Reference.


Using a naming service

Currently, ColdFusion can only resolve objects registered in a CORBA 2.3-compliant naming service.

If you use a naming service, make sure that its naming context is identical to the naming context specified in the property file of the Connector configuration in use, as specified in the ColdFusion Administrator CORBA Connectors page. The property file must contain the line "SVCnameroot=name" where name is the naming context to be used. The server implementing the object must bind to this context, and register the appropriate name.


Using CORBA objects in ColdFusion

After you create the object, you can invoke attributes and operations on the object using the syntax described in Creating and using objects. The following sections describe the rules for using CORBA objects in ColdFusion pages. They include information on using methods in ColdFusion, which IDL types you can access from ColdFusion, and the ColdFusion data types that correspond to the supported IDL data types.


Using CORBA interface methods in ColdFusion

When you use the cfobject tag or the CreateObject function to create a CORBA object, ColdFusion creates a handle to a CORBA interface, which is identified by the cfobject name attribute or the CreateObject function return variable. For example, the following CFML creates a handle named myHandle:

<cfobject  action = "create" type = "CORBA" context = "IOR"
class = "d:\temp\tester.ior" name = "myHandle" locale="visibroker">
<cfset myHandle = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "visibroker")

You use the handle name to invoke all of the interface methods, as in the following CFML:

<cfset ret=myHandle.method(foo)>

The following sections describe how to call CORBA methods correctly in ColdFusion.


Method name case considerations

Method names in IDL are case-sensitive. However, ColdFusion is case-insensitive. Therefore, do no use methods that differ only in case in IDL.

For example, the following IDL method declarations correspond to two different methods:

testCall(in string a); // method #1
TestCall(in string a); // method #2

However, ColdFusion cannot differentiate between the two methods. If you call either method, you cannot be sure which of the two will be invoked.


Passing parameters by value (in parameters)

CORBA in parameters are always passed by value. When calling a CORBA method with a variable in ColdFusion, specify the variable name without quotes, as shown in the following example:

IDL
void method(in string a);
CFML
<cfset foo="my string">
<cfset ret=handle.method(foo)>


Passing variables by reference (out and inout parameters)

CORBA out and inout parameters are always passed by reference. As a result, if the CORBA object modifies the value of the variable that you pass when you invoke the method, your ColdFusion page gets the modified value.

To pass a parameter by reference in ColdFusion, specify the variable name in double quotes in the CORBA method. The following example shows an IDL line that defines a method with a string variable, b, that is passed in and out of the method by reference. It also shows CFML that calls this method.

IDL
void method(in string a, inout string b);
CFML
<cfset foo = "My Initial String">
<cfset ret=handle.method(bar, "foo")>
<cfoutput>#foo#</cfoutput>

In this case, the ColdFusion variable foo corresponds to the inout parameter b. When the CFML executes, the following happens:

  1. ColdFusion calls the method, passing it the variable by reference.
  2. The CORBA method replaces the value passed in, "My Initial String", with some other value. Because the variable was passed by reference, this modifies the value of the ColdFusion variable.
  3. The cfoutput tag prints the new value of the foo variable.


Using methods with return values

Use CORBA methods that return values as you would any ColdFusion function; for example:

IDL
double method(out double a);
CFML
<cfset foo=3.1415>
<cfset ret=handle.method("foo")>
<cfoutput>#ret#</cfoutput>


Using IDL types with ColdFusion variables

The following sections describe how ColdFusion supports CORBA data types. They include a table of supported IDL types and information about how ColdFusion converts between CORBA types and ColdFusion data.


IDL Support

The following table shows which CORBA IDL types ColdFusion supports, and whether they can be used as parameters or return variables. (NA means not applicable.

CORBA IDL type | General support | As parameters | As return value
constants | No | No | No
attributes | Yes (for properties) | NA | NA
enum | Yes (as an integer) | Yes | Yes
union | No | No | No
sequence | Yes | Yes | Yes
array | Yes | Yes | Yes
interface | Yes | Yes | Yes
typedef | Yes | NA | NA
struct | Yes | Yes | Yes
module | Yes | NA | NA
exception | Yes | NA | NA
any | No | No | No
boolean | Yes | Yes | Yes
char | Yes | Yes | Yes
wchar | Yes | Yes | Yes
string | Yes | Yes | Yes
wstring | Yes | Yes | Yes
octet | Yes | Yes | Yes
short | Yes | Yes | Yes
long | Yes | Yes | Yes
float | Yes | Yes | Yes
double | Yes | Yes | Yes
unsigned short | Yes | Yes | Yes
unsigned long | Yes | Yes | Yes
longlong | No | No | No
unsigned longlong | No | No | No
void | Yes | NA | Yes

)


Data type conversion

The following table lists IDL data types and the corresponding ColdFusion data types.

IDL type | ColdFusion type
boolean | Boolean
char | One-character string
wchar | One-character string
string | String
wstring | String
octet | One-character string
short | Integer
long | Integer
float | Real number
double | Real number
unsigned short | Integer
unsigned long | Integer
void | Not applicable (returned as an empty string)
struct | Structure
enum | Integer, where 0 corresponds to the first enumerator in the enum type
array | Array (must match the array size specified in the IDL)
sequence | Array
interface | An object reference
module | Not supported (cannot dereference by module name)
exception | ColdFusion throws an exception of type coldfusion.runtime.corba.CorbaUserException
attribute | Object reference using dot notation


Boolean data considerations

ColdFusion treats any of the following as Boolean values:

True | "yes", "true", or 1
False | "no", "false", or 0

You can use any of these values with CORBA methods that take Boolean parameters, as the following code shows:

IDL
module Tester
   {
   interface TManager
   {
      void testBoolean(in boolean a);
      void testOutBoolean(out boolean a);
      void testInoutBoolean(inout boolean a);
      boolean returnBoolean();
   }
}
CFML
<CFSET handle = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "") >
<cfset ret = handle.testboolean("yes")>
<cfset mybool = True>
<cfset ret = handle.testoutboolean("mybool")>
<cfoutput>#mybool#</cfoutput>

<cfset mybool = 0>
<cfset ret = handle.testinoutboolean("mybool")>
<cfoutput>#mybool#</cfoutput>

<cfset ret = handle.returnboolean()>
<cfoutput>#ret#</cfoutput>


Struct data type considerations

For IDL struct types, use ColdFusion structures. You can prevent errors by using the same case for structure key names in ColdFusion as you do for the corresponding IDL struct field names.


Enum type considerations

ColdFusion treats the enum IDL type as an integer with the index starting at 0. As a result, the first enumerator corresponds to 0, the second to 1, and so on. In the following example, the IDL enumerator a corresponds to 0, b to 1 and c to 2:

IDL
module Tester
{
   enum EnumType {a, b, c};
   interface TManager
   {
      void testEnum(in EnumType a);
      void testOutEnum(out EnumType a);
      void testInoutEnum(inout EnumType a);
      EnumType returnEnum();
   }
}
CFML
<CFSET handle = CreateObject("CORBA", "d:\temp\tester.ior", "IOR", "") >
<cfset ret = handle.testEnum(1)>

In this example, the CORBA object gets called with the second (not first) entry in the enumerator, a.


Double-byte character considerations

If you are using an ORB that supports CORBA later than version 2.0, you do not have to do anything to support double-byte characters. Strings and characters in ColdFusion will appropriately convert to wstring and wchar when they are used. However, the CORBA 2.0 IDL specification does not support the wchar and wstring types, and uses the 8-bit Latin-1 character set to represent string data. In this case, you cannot pass parameters containing those characters, however, you can call parameters with char and string types using ColdFusion string data.


Handling exceptions

Use the cftry and cfcatch tags to catch CORBA object method exceptions thrown by the remote server, as follows:

  1. Specify type="coldfusion.runtime.corba.CorbaUserException" in the cfcatch tag to catch CORBA exceptions.
  2. Use the cfcatch.getContents method to get the contents of the exception object.

The the cfcatch.getContents method returns a ColdFusion structure containing the data specified by the IDL for the exception.

The following code example shows the IDL for a CORBA object that raises an exception defined by the PrimitiveException exception type definition, and the CFML that catches the exception and displays the contents of the object.

IDL
interface myInterface
{
   exception PrimitiveException
   {
      long l;
      string s;
      float f;
   };
   void testPrimitiveException() raises (PrimitiveException);

}

CFML
<cftry>
   <cfset ret0 = handle.testPrimitiveException()>
   <cfcatch type=coldfusion.runtime.corba.CorbaUserException>
      <cfset exceptStruct= cfcatch.getContents()>
      <cfdump var ="#exceptStruct#">
   </cfcatch>
</cftry>


CORBA Example

The following code shows an example of using a LoanAnalyzer CORBA object. This simplified object determines whether an applicant is approved for a loan based on the information that is supplied.

The LoanAnalyzer CORBA interface has one method, which takes the following two in arguments:

  • An Account struct that identifies the applicant’s account. It includes a Person struct that represents the account holder, and the applicant’s age and income.
  • A CreditCards sequence, which corresponds to the set of credit cards the user currently has. The credit card type is represented by a member of the CardType enumerator. (This example assumes the applicant has no more than one of any type of card.)

The object returns a Boolean value indicating whether the application is accepted or rejected.

The CFML does the following:

  1. Initializes the values of the ColdFusion variables that are used in the object method. In a more complete example, the information would come from a form, query, or both.

    2. The code for the Person and Account structs is straightforward. The cards variable, which represents the applicant’s credit cards, is more complex. The interface IDL uses a sequence of enumerators to represent the cards. ColdFusion represents an IDL sequence as an array, and an enumerator as 0-indexed number indicating the position of the selected item among the items in the enumerator type definition.

    In this case, the applicant has a Master Card, a Visa card, and a Diners card. Because Master Card (MC) is the first entry in the enumerator type definition, it is represented in ColdFusion by the number 0. Visa is the third entry, so it is represented by 2. Diners is the fifth entry, so it is represented by 4. These numbers must be put in an array to represent the sequence, resulting in a three-element, one-dimensional array containing 0, 2, and 4.

  2. Instantiates the CORBA object.
  3. Calls the approve method of the CORBA object and gets the result in the return variable, ret.
  4. Displays the value of the ret variable, Yes or No.

IDL

struct Person
{
   long pid;
   string name;
   string middle;
   string last_name;
}

struct Account
{
   Person person;
   short age;
   double income;
}

double loanAmountl
enum cardType {AMEX, VISA, MC, DISCOVER, DINERS};

typedef sequence<cardType> CreditCards;

interface LoanAnalyzer
{
   boolean approve( in Account, in CreditCards);
}

CFML

<!--- Declare a "person" struct ---->
<cfset p = StructNew()>
<cfif IsStruct(p)>
   <cfset p.pid = 1003232>
   <cfset p.name = "Eduardo">
   <cfset p.middle = "R">
   <cfset p.last_name = "Doe">
</cfif>

<!---- Declare an "Account" struct --->
<cfset a = StructNew()>
<cfif IsStruct(a)>
   <cfset a.person = p>
   <cfset a.age = 34>
   <cfset a.income = 150120.50>
</cfif>

<!----- Declare a "CreditCards" sequence --->
<cfset cards = ArrayNew(1)>
<cfset cards[1] = 0>   <!--- corresponds to Amex --->
<cfset cards[2] = 2>   <!--- corresponds to MC --->
<cfset cards[3] = 4>   <!--- corresponds to Diners --->

<!---- Creating a CORBA handle using the Naming Service---->
<cfset handle = CreateObject("CORBA", "FirstBostonBank/MA/Loans",
"NameService") >

<cfset ret=handle.approve(a, cards)>
<cfoutput>Account approval: #ret#</cfoutput>
Previous


Sending and Receiving E-mail

You can add interactive e-mail features to your ColdFusion applications using the cfmail and cfpop tags. This complete two-way interface to mail servers makes the ColdFusion e-mail capability a vital link to your users.

Contents
  • Using ColdFusion with mail servers
  • Sending e-mail messages
  • Sample uses of cfmail
  • Customizing e-mail for multiple recipients
  • Using cfmailparam
  • Advanced sending options
  • Receiving e-mail messages
  • Handling POP mail
Next


Using ColdFusion with mail servers

Adding e-mail to your ColdFusion applications lets you respond automatically to user requests. You can use e-mail in your ColdFusion applications in many different ways, including the following:

  • Trigger e-mail messages based on users’ requests or orders.
  • Allow users to request and receive additional information or documents through e-mail.
  • Confirm customer information based on order entries or updates.
  • Send invoices or reminders, using information pulled from database queries.

ColdFusion offers several ways to integrate e-mail into your applications. To send e-mail, you generally use the Simple Mail Transfer Protocol (SMTP). To receive e-mail, you use the Post Office Protocol (POP) to retrieve e-mail from the mail server. To use e-mail messaging in your ColdFusion applications, you must have access to an SMTP server and/or a valid POP account.

In your ColdFusion application pages, you use the cfmail and cfpop tags to send and receive e-mail, respectively. The following sections describe how to use the ColdFusion e-mail features and show examples of these tags.


Sending e-mail messages

Before you configure ColdFusion to send e-mail messages, you must have access to an SMTP e-mail server. Also, before you run application pages that refer to the e-mail server, you can configure the ColdFusion Administrator to use the SMTP server. If you later need to override the SMTP server information, you can specify a new mail server in the server attribute of the cfmail tag.

To configure ColdFusion for e-mail:

  1. In the ColdFusion Administrator, select Server Settings > Mail Server.
  2. In the Mail Server box, enter the name or IP address of your SMTP mail server.
  3. (Optional) Change the Server Port and Connection Timeout default settings.
  4. Select the Verify Mail Server Connection check box to make sure ColdFusion can access your mail server.
  5. (Optional) Change the Server Port and Connection Timeout default settings.
  6. Click Submit Changes.

    7. ColdFusion saves the settings. The page displays a message indicating success or failure for connecting to the server.

For more information on the Administrator’s mail settings, see Administering ColdFusion MX.


Sending SMTP e-mail with cfmail

The cfmail tag provides support for sending SMTP e-mail from within ColdFusion applications. The cfmail tag is similar to the cfoutput tag, except that cfmail outputs the generated text as SMTP mail messages rather than to a page. The cfmail tag supports all the attributes and commands that you use with cfoutput, including query. The following table describes important cfmail tag attributes:

Attribute | Description
subject | The subject of the message.
from | The e-mail address of the sender.
to | The e-mail address of the recipient. Use a comma-delimited list to specify multiple recipients.
cc | (Optional) The e-mail address of a carbon copy recipient. The recipient’s address is visible to other recipients. Use a comma-delimited list to specify multiple cc recipients.
bcc | (Optional) The e-mail address of a blind carbon copy recipient. The recipient’s address is not visible to other recipients. Use a comma-delimited list to specify multiple bcc recipients.
SpoolEnable | (Optional) When SpoolEnable="yes", saves a copy of the message until the sending operation is complete.

To send a simple e-mail message:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Sending a simple e-mail</title>
</head>

<body>
<h1>Sample e-mail</h1>
<cfmail
   from="Sender@Company.com"
   to="#URL.email#"
   subject="Sample e-mail from ColdFusion MX">

This is a sample e-mail message to show basic e-mail capability.

</cfmail>

The e-mail was sent.

</body>
</html>
  2. Save the file as send_mail.cfm in the myapps directory under your web_root.
  3. Open your browser and enter the following URL:

    4. http://localhost:8500/myapps/send_mail.cfm?email=myname@mycompany.com

    (Replace myname@mycompany.com with your e-mail address.)

    The page sends the e-mail to you, through your SMTP server.

Note: If you do not receive an e-mail message, check whether you have configured ColdFusion to work with your SMTP server; for more information, see Sending e-mail messages.


Sample uses of cfmail

An application page containing the cfmail tag dynamically generates e-mail messages based on the tag’s settings. Some of the tasks that you can accomplish with cfmail include the following:

  • Sending a mail message in which the data the user enters in an HTML form determine the recipient and contents
  • Using a query to send a mail message to a database-driven list of recipients
  • Using a query to send a customized mail message, such as a billing statement, to a list of recipients that is dynamically populated from a database
  • Sending a MIME file attachment with a mail message


Sending form-based e-mail

In the following example, the contents of a customer inquiry form submittal are forwarded to the marketing department. You could also use the same application page to insert the customer inquiry into the database. You include the following code on your form so that it executes when users enter their information and submit the form:

<cfmail
   from="#Form.EMailAddress#"
   to="marketing@MyCompany.com,sales@MyCompany.com"
   subject="Customer Inquiry">

A customer inquiry was posted to our web site:

Name: #Form.FirstName# #Form.LastName#
Subject: #Form.Subject#

#Form.InquiryText#
</cfmail>


Sending query-based e-mail

In the following example, a query (ProductRequests) retrieves a list of the customers who inquired about a product during the previous seven days. The list is then sent, with an appropriate header and footer, to the marketing department:

<cfmail
   query="ProductRequests"
   from="webmaster@MyCompany.com"
   to="marketing@MyCompany.com"
   subject="Widget status report">

Here is a list of people who have inquired about
MyCompany Widgets during the previous seven days:

<cfoutput>
#ProductRequests.FirstName# #ProductRequests.LastName# (#ProductRequests.Company#)
- #ProductRequests.EMailAddress#&##013;
</cfoutput>

Regards,
The WebMaster
webmaster@MyCompany.com

</cfmail>


Reviewing the code

The following table describes the code:

Code
Description
<cfoutput>
#ProductRequests.FirstName#
#ProductRequests.LastName#
(#ProductRequests.Company#) -
#ProductRequests.EMailAddress#&##013;
</cfoutput>
Presents a dynamic list embedded within a normal cfmail message, repeating for each row in the ProductRequests query. The &##013; forces a carriage return between output records.


Sending e-mail to multiple recipients

In addition to simply using a comma-delimited list in the to attribute of the cfmail tag, you can send e-mail to multiple recipients by using the query attribute of the cfmail tag.

In the following example, a query (BetaTesters) retrieves a list of people who are beta testing ColdFusion. This query then notifies each beta tester that a new release is available. The contents of the cfmail tag body are not dynamic. What is dynamic is the list of e-mail addresses to which the message is sent. Using the variable #TesterEMail#, which refers to the TesterEmail column in the Betas table, in the to attribute enables the dynamic list:

<cfquery name="BetaTesters" datasource="myDSN">
   SELECT * FROM BETAS
</cfquery>

<cfmail query="BetaTesters"
   from="beta@MyCompany.com"
   to="#BetaTesters.TesterEMail#"
   subject="Widget Beta Four Available">

To all Widget beta testers:

Widget Beta Four is now available
for downloading from the MyCompany site.
The URL for the download is:

http://beta.mycompany.com

Regards,
Widget Technical Support
beta@MyCompany.com

</cfmail>


Customizing e-mail for multiple recipients

In the following example, a query (GetCustomers) retrieves the contact information for a list of customers. The query then sends an e-mail to each customer to verify that the contact information is still valid:

<cfquery name="GetCustomers" datasource="myDSN">
   SELECT * FROM Customers
</cfquery>

<cfmail query="GetCustomers"
   from="service@MyCompany.com"
   to="#GetCustomers.EMail#"
   subject="Contact Info Verification">

Dear #GetCustomers.FirstName# -

We'd like to verify that our customer
database has the most up-to-date contact
information for your firm. Our current
information is as follows:

Company Name: #GetCustomers.Company#
Contact: #GetCustomers.FirstName# #GetCustomers.LastName#

Address:
   #GetCustomers.Address1#
   #GetCustomers.Address2#
   #GetCustomers.City#, #GetCustomers.State# #GetCustomers.Zip#

Phone: #GetCustomers.Phone#
Fax: #GetCustomers.Fax#
Home Page: #GetCustomers.HomePageURL#

Please let us know if any of the above
information has changed, or if we need to
get in touch with someone else in your
organization regarding this request.

Thanks,
Customer Service
service@MyCompany.com

</cfmail>


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfquery name="GetCustomers"
datasource="myDSN">
   SELECT * FROM Customers
</cfquery>
Retrieves all data from the Customers table into a query named GetCustomers.
<cfmail query="GetCustomers"
   from="service@MyCompany.com"
   to="#GetCustomers.EMail#"
   subject="Contact Info
Verification">
Uses the to attribute of cfmail, the #GetCustomers.Email# query column causes one message to be sent to the address listed in each row of the query. Therefore, the mail body does not use a cfoutput tag.
Dear #GetCustomers.FirstName#
...
Company Name: #GetCustomers.Company#
Contact: #GetCustomers.FirstName#
#GetCustomers.LastName#

Address:
   #GetCustomers.Address1#
   #GetCustomers.Address2#
   #GetCustomers.City#,
#GetCustomers.State#
#GetCustomers.Zip#

Phone: #GetCustomers.Phone#
Fax: #GetCustomers.Fax#
Home Page: #GetCustomers.HomePageURL#
Uses other query columns (#GetCustomers.FirstName#, #GetCustomers.LastName#, and so on) within the cfmail section to customize the contents of the message for each recipient.


Using cfmailparam

You use the cfmailparam tag to attach files or add a custom header to an e-mail message. You nest the cfmailparam tag within the cfmail tag.


Attaching files to a message

You use one cfmailparam tag for each attachment, as the following example shows:

<cfmail from="daniel@MyCompany.com"
   to="jacob@YourCompany.com"
   subject="Requested Files">

Jake,

Here are the files you requested.

Regards,
Dan

<cfmailparam file="c:\widget_launch\photo_01.jpg">
<cfmailparam file="c:\widget_launch\press_release.doc">

</cfmail>

You must use a fully qualified system path for the file attribute of cfmailparam. The file must be located on a drive on the ColdFusion server machine (or a location on the local network), not the browser machine.


Adding a custom header to a message

When the recipient of an e-mail message replies to the message, the reply is sent to the address specified in the From field of the original message. You can use cfmailparam to override the value in the From field and provide a Reply-To e-mail address. Using cfmailparam, the reply to the following example is addressed to widget_master@YourCompany.com:

<cfmail from="jacob@YourCompany.com"
   to="daniel@MyCompany.com"
   subject="Requested Files">
<cfmailparam name="Reply-To" value="widget_master@YourCompany.com">

Dan,
Thanks very much for the sending the widget press release and graphic.
I’m now the company’s Widget Master and am accepting e-mail at
widget_master@YourCompany.com.

See you at Widget World 2002!

Jake
</cfmail>

Note: You can combine the two uses of cfmailparam within the same ColdFusion page. Write a separate cfmailparam tag for each header and for each attached file.


Advanced sending options

The ColdFusion implementation of SMTP mail uses a spooled architecture. When an application page processes a cfmail tag, the messages that are generated are not sent immediately. Instead, they are spooled to disk and processed in the background. This architecture has two advantages:

  • End users of your application are not required to wait for SMTP processing to complete before a page returns to them. This design is especially useful when a user action causes more than a handful of messages to be sent.
  • Messages sent using cfmail are delivered reliably, even in the presence of unanticipated events like power outages or server crashes.

You can set how frequently ColdFusion Server checks for spooled mail on messages on the Mail/Mail Logging page of the ColdFusion Administrator Server tab. (The default interval is 60 seconds.) If ColdFusion is extremely busy or has a large existing queue of messages, however, delivery can occur after the spool interval.


Sending mail as HTML

Most newer Internet mail applications are capable of reading and interpreting HTML code in a mail message. The cfmail tag lets you specify the message type as HTML. The type="HTML" attribute (the only valid value; the default is plain text) informs the receiving e-mail client that the message contains embedded HTML tags that must be processed. This feature is useful only when you are sending messages to mail clients that can interpret HTML. Also, you must escape any pound signs in the HTML, such as those used to specify colors, by using two # characters; for example, bgcolor="##C5D9E5".


Error logging and undelivered messages

ColdFusion logs all errors that occur during SMTP message processing to the file mail.log in the ColdFusion log directory. The log entries contain the date and time of the error as well as diagnostic information about why the error occurred.

If a message is not delivered because of an error, ColdFusion writes it to this directory:

  • On Windows: \CFusionMX\Mail\UnDelivr
  • On UNIX: /opt/coldfusionmx/mail/undelivr

The error log entry that corresponds to the undelivered message contains the name of the file written to the UnDelivr (or undelivr) directory.

For more information about the mail logging settings in the ColdFusion Administrator, see Administering ColdFusion MX.


Receiving e-mail messages

You create ColdFusion pages to access a Post Office Protocol (POP) server to retrieve e-mail message information. ColdFusion can then display the messages (or just header information), write information to a database, or perform other actions.

The cfpop tag lets you add Internet mail client features and e-mail consolidation to applications. Although a conventional mail client provides an adequate interface for personal mail, there are many cases in which an alternative interface to some mailboxes is advantageous. You use cfpop to develop targeted mail clients to suit the specific needs of a wide range of applications. The cfpop tag does not work with the other major e-mail protocol, Internet Mail Access Protocol (IMAP).

Here are three instances in which implementing POP mail makes sense:

  • If your site has generic mailboxes that are read by more than one person (sales@yourcompany.com), it can be more efficient to construct a ColdFusion mail front end to supplement individual user mail clients.
  • In many applications, you can automate mail processing when the mail is formatted to serve a particular purpose; for example, when subscribing to a list server.
  • If you want to save e-mail messages to a database.

Using cfpop on your POP server is like running a query on your mailbox contents. You set its action attribute to retrieve either headers (using the GetHeaderOnly value) or entire messages (using the GetAll value) and assign it a name value. You use the name to refer to the record set that cfpop returns, for example, when using cfoutput. To access a POP server, you also must define the server, username, and password attributes.

For more information on cfpop syntax and variables, see the CFML Reference.


Using cfpop

Use the following steps to add POP mail to your application.

To implement the cfpop tag in your application:

  1. Choose the mailboxes to access within your ColdFusion application.
  2. Determine which mail message components you must process: message header, message body, attachments, and so on.
  3. Decide whether you must store the retrieved messages in a database.
  4. Decide whether you must delete messages from the POP server after you retrieve them.
  5. Incorporate the cfpop tag in your application and create a user interface for accessing a mailbox.
  6. Build an application page to handle the output. Retrieved messages can include ASCII characters that do not display properly in the browser.

You use the cfoutput tag with the HTMLCodeFormat and HTMLEditFormat functions to control output to the browser. These functions convert characters with special meanings in HTML, such as the less than (<), greater than (>), and ampersand (&) symbols, into HTML-escaped characters, such as &lt;, &gt;, and &amp;. The HTMLCodeFormat tag also surrounds the text in a pre tag block. The examples in this chapter use these functions.


cfpop query variables

Like any ColdFusion query, each cfpop query returns two variables that provide record number information:

  • RecordCount The total number of records returned by the query.
  • CurrentRow The current row of the query being processed by cfoutput or cfloop in a query-driven loop.

You can reference these properties in a cfoutput tag by prefixing the query variable with the query name in the name attribute of cfpop:

<cfoutput>

This operation returned #Sample.RecordCount# messages.

</cfoutput>


Handling POP mail

This section provides an example of each of the following usages:

  • Retrieving only message headers
  • Retrieving a message
  • Retrieving a message and its attachments
  • Deleting messages


Retrieving only message headers

You can retrieve only the headers of your messages by using the GetHeaderOnly value for the action attribute of the cfpop tag. Whether you use cfpop to retrieve the header or the entire message, ColdFusion returns a query object that contains one row for each message in the specified mailbox. The query object, whose name is specified in the name attribute of the cfpop tag, consists of the following fields:

  • date
  • from
  • messageNumber
  • replyTo
  • subject
  • cc
  • to

To retrieve only the message header:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>POP Mail Message Header Example</title>
</head>

<body>
<h2>This example retrieves message header information:</h2>

<cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
   action="GetHeaderOnly"
   name="Sample">

<cfoutput query="Sample">
   MessageNumber: #HTMLEditFormat(Sample.messageNumber)# <br>
   To: #HTMLEditFormat(Sample.to)# <br>
   From: #HTMLEditFormat(Sample.from)# <br>
   Subject: #HTMLEditFormat(Sample.subject)# <br>
   Date: #HTMLEditFormat(Sample.date)#<br>
    Cc: #HTMLEditFormat(Sample.cc)# <br>
   ReplyTo: #HTMLEditFormat(Sample.replyTo)# <br><br>
</cfoutput>

</body>
</html>
  2. Edit the following lines so that they refer to valid values for your POP mail server, username, and password:
    3. <cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
  3. Save the file as header_only.cfm in the myapps directory under your web_root and view it in your web browser:

    4. This is a picture of the feature being described.

    This code retrieves the message headers and stores them in a cfpop record set called Sample. For more information about working with record set data, see Using Query of Queries.

The ColdFusion function HTMLEditFormat replaces characters that have meaning in HTML, such as the less than (<) and greater than (>) signs that can surround detailed e-mail address information, with escaped characters such as &lt; and &gt;.

In addition, you can process the date returned by cfpop with ParseDateTime, which accepts an argument for converting POP date/time objects into a CFML date-time object.

You can reference any of these columns in a cfoutput tag, as the following example shows:

<cfoutput>
   #ParseDateTime(queryname.date, "POP")#
   #HTMLCodeFormat(queryname.from)#
   #HTMLCodeFormat(queryname.messageNumber)#
</cfoutput>

For information on these ColdFusion functions, see the CFML Reference.


Retrieving a message

When you use the cfpop tag with action="GetAll", ColdFusion returns the same columns as with getheaderonly, plus two additional columns, body and header.

To retrieve an entire message:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head><title>POP Mail Message Body Example</title></head>

<body>
<h2>This example adds retrieval of the message body:</h2>
<cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
   action="GetAll"
   name="Sample">

<cfoutput query="Sample">
   MessageNumber: #HTMLEditFormat(Sample.messageNumber)# <br>
   To: #Sample.to# <br>
   From: #HTMLEditFormat(Sample.from)# <br>
   Subject: #HTMLEditFormat(Sample.subject)# <br>
   Date: #HTMLEditFormat(Sample.date)#<br>
   Cc: #HTMLEditFormat(Sample.cc)# <br>
   ReplyTo: #HTMLEditFormat(Sample.replyTo)# <br>
   <br>
   Body:<br>
   #Sample.body#<br>
   <br>
   Header:<br>
   #HTMLCodeFormat(Sample.header)#<br>
   <hr>
   </cfoutput>

</body>

</html>
  1. Edit the following lines so that they refer to valid values for your POP mail server, username, and password:
    2. <cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
  2. Save the file as header_body.cfm in the myapps directory under your web_root and view it in your web browser:

    3. This is a picture of the feature being described.

This example does not use a CFML function to encode the body contents. As a result, the browser displays the formatted message as you would normally see it in a mail program that supports HTML messages.


Retrieving a message and its attachments

When you use the cfpop tag with action="getAll", and use the attachmentpath attribute to specify the directory in which to store attachments, ColdFusion retrieves any attachment files from the POP server and saves them in the specified directory. The cfpop tag also adds the following two columns to the query it creates:

  • attachments Contains a tab-separated list of all attachment names.
  • attachmentfiles  Contains a tab-separated list of the locations of the attachment files. Use the cffile tag to delete these temporary files.

You must ensure that the attachmentpath directory exists before you use the cfpop tag to retrieve attachments. ColdFusion generates an error if it attempts to write an attachment file to a nonexistent directory.

If a message has no attachments, the attachments and attachmentfiles columns contain empty strings.

To retrieve all parts of a message, including attachments:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>POP Mail Message Attachment Example</title>
</head>

<body>
<h2>This example retrieves message header,
body, and all attachments:</h2>

<cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
   action="GetAll"
   attachmentpath="c:\temp\attachments"
   name="Sample">

<cfoutput query="Sample">
   MessageNumber: #HTMLEditFormat(Sample.MessageNumber)# <br>
   To: #HTMLEditFormat(Sample.to)# <br>
   From: #HTMLEditFormat(Sample.from)# <br>
   Subject: #HTMLEditFormat(Sample.subject)# <br>
   Date: #HTMLEditFormat(Sample.date)# <br>
   Cc: #HTMLEditFormat(Sample.cc)# <br>
   ReplyTo: #HTMLEditFormat(Sample.ReplyTo)# <br>
   Attachments: #HTMLEditFormat(Sample.Attachments)# <br>
   Attachment Files: #HTMLEditFormat(Sample.AttachmentFiles)# <br>
   <br>
   Body:<br>
   #Sample.body# <br>
   <br>
   Header:<br>
   HTMLCodeFormat(Sample.header)# <br>
   <hr>
</cfoutput>

</body>
</html>
  2. Edit the following lines so that they refer to valid values for your POP mail server, username, and password:
    3. <cfpop server="mail.company.com"
   username=#myusername#
   password=#mypassword#
  3. Save the file as header_body_att.cfm in the myapps directory under your web_root and view it in your web browser:

    4. This is a picture of the feature being described.

Note: To avoid duplicate filenames when saving attachments, set the generateUniqueFilenames attribute of cfpop to Yes.


Deleting messages

By default, retrieved messages remain on the POP mail server. If you want to delete retrieved messages, you must set the action attribute of the cfpop tag to Delete. You must also specify use the messagenumber attribute to specify the numbers of the messages to delete.

Using cfpop to delete a message permanently removes it from the server. If the messagenumber does not correspond to a message on the server, ColdFusion generates an error.

Note: Message numbers are reassigned at the end of every POP mail server communication that contains a delete action. For example, if you retrieve four messages from a POP mail server, the server returns the message numbers 1,2,3,4. If you delete messages 1 and 2 with a single cfpop tag, messages 3 and 4 are assigned message numbers 1 and 2, respectively.

To delete messages:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
<title>POP Mail Message Delete Example</title>
</head>

<body>
<h2>This example deletes messages:</h2>

<cfpop server="mail.company.com"
   username=#username#
   password=#password#
   action="Delete"
   messagenumber="1,2,3">

</body>
</html>
  2. Edit the following lines so that they refer to valid values for your POP mail server, username, and password:
    3. <cfpop server="mail.company.com"
   username=#username#
   password=#password#
  3. Save the file as message_delete.cfm in the myapps directory under your web_root and view the file in your web browser.

Caution:When you view this page in your web browser, ColdFusion immediately deletes the messages from the POP server.

The following figure shows the message list before the deletion of message 280:

This is a picture of the feature being described.

The following figure shows the message list after the deletion of message number 280. Notice that ColdFusion reorders the remaining messages:

This is a picture of the feature being described.

Previous


Interacting with Remote Servers

This chapter describes how ColdFusion wraps the complexity of Hypertext Transfer Protocol (HTTP) and File Transfer Protocol (FTP) communications in a simplified tag syntax that lets you extend your site’s offerings across the web.

Contents
  • About interacting with remote servers
  • Using cfhttp to interact with the web
  • Creating a query object from a text file
  • Using the cfhttp Post method
  • Performing file operations with cfftp
Next


About interacting with remote servers

Transfer protocols are mechanisms for moving files and information from a source to one or more destinations. Two of the more popular protocols are the Hypertext Transfer Protocol (HTTP) and the File Transfer Protocol (FTP). ColdFusion has the cfhttp and cfftp tags that let you use these protocols to interact with remote servers.

The cfhttp tag lets you receive a web page or web-based file, just as a web browser uses HTTP to transport web pages. When you type a URL into a web browser, you make an HTTP request to a web server. With the cfhttp tag, you can display a web page, send variables to a ColdFusion or CGI application, retrieve specialized content from a web page, and create a ColdFusion query from a text file. You can use the Get or Post methods to interact with remote servers.

The cffttp tag takes advantage of FTP’s main purpose--transporting files. Unlike HTTP, FTP was not designed to interact with other servers for processing and interacting with data. Once you establish an FTP connection with the cffttp tag, you can use it to upload, download, and manage files and directories.


Using cfhttp to interact with the web

The cfhttp tag, which lets you retrieve information from a remote server, is one of the more powerful tags in the CFML tag set. You can use one of two methods--Get or Post--to interact with a remote server using the cfhttp tag.

  • Using the Get method, you can only send information to the remote server in the URL. This method is often used for a one-way transaction in which cfhttp retrieves an object.
  • Using the Post method, you can pass variables to a ColdFusion page or CGI program, which processes them and returns data to the calling page. The calling page then appears or further processes the data that was received. For example, when you use cfhttp to Post to another ColdFusion page, that page does not appear. It processes the request and returns the results to the original ColdFusion page, which then uses the information as appropriate.


Using the cfhttp Get method

You use Get to retrieve files, including text and binary files, from a specified server. The retrieved information is stored in a special variable, cfhttp.fileContent. The following examples illustrate several common Get operations.

To retrieve a file and store it in a variable:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Use Get Method</title>
</head>

<body>
<cfhttp
   method="Get"
   url="http://www.macromedia.com"
   resolveurl="Yes">
<cfoutput>
   #cfhttp.FileContent# <br>
</cfoutput>

</body>
</html>
  2. (Optional) Replace the value of the url attribute with another URL.
  3. Save the file as get_webpage.cfm in the myapps directory under your web_root and view it in the web browser.

    4. The browser loads the web page specified in the url attribute:

    This is a picture of the feature being described.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfhttp method="Get"
   url="http://www.macromedia.com"
   resolveurl="Yes">
Get the page specified in the URL and make the links absolute instead of relative so that they appear properly.
<cfoutput>
   #cfhttp.FileContent# <br>
</cfoutput>
Display the page, which is stored in the variable cfhttp.fileContent, in the browser.

To get a web page and save it in a file:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Use Get Method</title>
</head>

<body>
<cfhttp
   method = "Get"
   url="http://www.macromedia.com/software"
   path="c:\temp"
   file="macr_software.htm">

</body>
</html>
  2. (Optional) Replace the value of the url attribute with another URL and change the filename.
  3. (Optional) Change the path from C:\temp to a path on your hard drive.
  4. Save the page as save_webpage.cfm in the myapps directory under your web_root.
  5. Go to the specified path and view the file that you specified in a text editor (using the above values, this is C:\temp\macr_software.htm):

    6. This is a picture of the feature being described.

    The saved file does not appear properly in your browser because the Get operation saves only the specified web page HTML. It does not save the frame, image, or other files that the page might include.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfhttp
   method = "Get"
   url="http://www.redcross.org/news"
   path="c:\temp"
   file="rc_news.htm">
Get the page specified in the URL and save it in the file specified by the path and file attributes.
When you use the path and file attributes, ColdFusion ignores any resolveurl attribute. As a result, frames and other included files cannot appear when you view the saved page.

To get a binary file and save it:

  1. Create a ColdFusion page with the following content:
    2. <cfhttp
      method="Get"
      url="http://www.macromedia.com/macromedia/accessibility/images/
spotlight.jpg"
      path="c:\temp"
      file="My_SavedBinary.jpg">
<cfoutput>
   #cfhttp.MimeType#
</cfoutput>
  2. (Optional) Replace the value of the url attribute with the URL of a binary file that you want to download.
  3. (Optional) Change the path from C:\temp to a path on your hard drive.
  4. Save the file as save_binary.cfm in the myapps directory under your web_root and view it in the web browser.

    5. The MIME content type appears in your browser:

    This is a picture of the feature being described.

  5. (Optional) Verify that the binary file now exists at the location you specified in the path attribute.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfhttp
   method="Get"
   url="http://www.dendwrite.com/images/dw_neuron98.gif"
   path="c:\temp"
   file="My_SavedBinary.zip">
Get a binary file and save it in the path and file specified.
<cfoutput>
   #cfhttp.MimeType#
</cfoutput>
Display the MIME type of the file.


Creating a query object from a text file

You can create a query object from a delimited text file by using the cfhttp tag and specifying method="Get" and the name attribute. This is a powerful method for processing and handling text files. After you create the query object, you can easily reference columns in the query and perform other ColdFusion operations on the data.

ColdFusion processes text files in the following manner:

  • You can specify a field delimiter with the delimiter attribute. The default is a comma.
  • If data in a field might include the delimiter character, you must surround the entire field with the text qualifier character, which you can specify with the textqualifier attribute. The default text qualifier is the double quotation mark (").
  • textqualifier="" specifies that there is no text qualifier. textqualifier="""" (four " marks in a row) explicitly specifies the double quotation mark as the text qualifier.
  • If there is a text qualifier, you must surround all field values with the text qualifier character.
  • To include the text qualifier character in a field, use a double character. For example, if the text qualifier is ", use "" to include a quotation mark in the field.
  • The first row of text is always interpreted as column headings, so that row is skipped. You can override the file’s column heading names by specifying a different set of names in the columns attribute. You must specify a name for each column. You then use these new names in your CFML code. However, ColdFusion never treats the first row of the file as data.
  • When duplicate column heading names are encountered, ColdFusion adds an underscore character to the duplicate column name to make it unique. For example, if two CustomerID columns are found, the second is renamed "CustomerID_".

To create a query from a text file:

  1. Create a text file with the following content:
    2. OrderID,OrderNum,OrderDate,ShipDate,ShipName,ShipAddress
001,001,01/01/01,01/11/01,Mr. Shipper,123 Main Street
002,002,01/01/01,01/28/01,Shipper Skipper,128 Maine Street
  2. Save the file as text.txt in the myapps directory under your web_root.
  3. Create a ColdFusion page with the following content:
    4. <cfhttp method="Get"
   url="http://127.0.0.1/myapps/text.txt"
   name="juneorders"
   textqualifier="">

<cfoutput query="juneorders">
   OrderID: #OrderID#<br>
   Order Number: #OrderNum#<br>
   Order Date: #OrderDate#<br>
</cfoutput>
<!--- Now substitute different column names --->
<!--- by using the columns attribute --->
<hr>
Now using replacement column names<br>

<cfhttp method="Get"
   url="http://127.0.0.1/myapps/text.txt"
   name="juneorders"
   columns="ID,Number,ODate,SDate,Name,Address"
   textqualifier="">

<cfoutput query="juneorders">
   Order ID: #ID#<br>
   Order Number: #Number#<br>
   Order Date: #SDate#<br>
</cfoutput>
  4. Save the file as query_textfile.cfm in the myapps directory under your web_root and view it in the web browser:

    5. This is a picture of the feature being described.


Using the cfhttp Post method

Use the Post method to send cookie, form field, CGI, URL, and file variables to a specified ColdFusion page or CGI program for processing. For Post operations, you must use the cfhttpparam tag for each variable you want to post. The Post method passes data to a specified ColdFusion page or an executable that interprets the variables being sent and returns data.

For example, when you build an HTML form using the Post method, you specify the name of the page to which form data is passed. You use the Post method in cfhttp in a similar way. However, with cfhttp, the page that receives the Post does not, itself, display anything.

To pass variables to a ColdFusion page:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>HTTP Post Test</title>
</head>

<body>
<h1>HTTP Post Test</h1>

<cfhttp method="Post"
   url="http://127.0.0.1:8500/myapps/post_test_server.cfm">

   <cfhttpparam type="Cookie"
      value="cookiemonster"
      name="mycookie6">
   <cfhttpparam type="CGI"
      value="cgivar "
      name="mycgi">
   <cfhttpparam type="URL"
      value="theurl"
      name="myurl">
   <cfhttpparam type="Formfield"
      value="twriter@macromedia.com"
      name="emailaddress">
   <cfhttpparam type="File"
      name="myfile"
      file="c:\pix\trees.gif">
</cfhttp>

<cfoutput>
File Content:<br>
   #cfhttp.filecontent#<br>
<br>
Mime Type:  #cfhttp.MimeType#<br>
</cfoutput>
</body>
</html>
  2. Replace the path to the GIF file to a path on your server (this is just before the closing cfhttp tag).
  3. Save the file as post_test.cfm in the myapps directory under your web_root.

Note: You must write a page to view the variables. This is the next procedure.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfhttp method="Post"
   url="http://127.0.0.1:8500/myapps/
post_test_   server.cfm">
Post an HTTP request to the specified page.
<cfhttpparam type="Cookie"
   value="cookiemonster"
   name="mycookie6">
Send a cookie in the request.
<cfhttpparam type="CGI"
   value="cgivar "
   name="mycgi">
Send a CGI variable in the request.
   <cfhttpparam type="URL"
      value="theurl"
      name="myurl">
Send a URL in the request.
<cfhttpparam type="Formfield"
   value="twriter@macromedia.com"
   name="emailaddress">
Send a Form field in the request.
<cfhttpparam type="File"
   name="myfile"
   file="c"\pix\trees.gif">
Send a file in the request.
The </cfhttp> tag ends the http request.
<cfoutput>
File Content:<br>
   #cfhttp.filecontent#<br>
Display the contents of the file that the page that is posted to creates by processing the request. In this example, this is the output from the cfoutput tag in server.cfm.
Mime Type:  #cfhttp.MimeType#<br>
</cfoutput>
Display the MIME type of the created file.

To view the variables:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head><title>HTTP Post Test</title> </head>

<body>
<h1>HTTP Post Test</h1>
<cffile destination="C:\temp\"
   nameconflict="Overwrite"
   filefield="Form.myfile"
   action="Upload"
   attributes="Normal">

<cfoutput>
   The URL variable is: #URL.myurl# <br>
   The Cookie variable is: #Cookie.mycookie6# <br>
   The CGI variable is: #CGI.mycgi#. <br>
   The Formfield variable is: #Form.emailaddress#. <br>
   The file was uploaded to #File.ServerDirectory#\#File.ServerFile#.
</cfoutput>

</body>
</html>
  2. Replace C:\temp\ with an appropriate directory path on your hard drive.
  3. Save the file as post_test_server.cfm in the myapps directory under your web_root.
  4. View post_test.cfm in your browser and look for the file in C:\temp\ (or your replacement path):

    5. This is a picture of the feature being described.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cffile destination="C:\temp\"
   nameconflict="Overwrite"
   filefield="Form.myfile"
   action="Upload"
   attributes="Normal">
Write the transferred document to a file on the server. Note that you send the file using the cfhttpparam type="File" attribute, but the receiving page gets it as a Form variable, not a File variable. This cffile tag creates File variables, as follows.
<cfoutput>
Output information. The results are not displayed by this page. They are passed back to the posting page in its cfhttp.filecontent variable.
The URL variable is: #URL.myurl# <br>
Output the value of the URL variable sent in the HTTP request.
The Cookie variable is: #Cookie.mycookie# <br>
Output the value of the Cookie variable sent in the HTTP request.
The CGI variable is: #CGI.mycgi# <br>
Output the value of the CGI variable sent in the HTTP request.
The Form variable is:
#Form.emailaddress#. <br>
Output the Form variable sent in the HTTP request. Note that you send the variable using the type="formField" attribute but the receiving page gets it as a Form variable.
The file was uploaded to
#File.ServerDirectory#\#File.
ServerFile#.
</cfoutput>
Output the results of the cffile tag on this page. This time, the variables really are File variables.


To return results of a CGI program:

The following code runs a CGI program search.exe on a website and displays the results, including both the MIME type and length of the response. The search.exe program must expect a “search” parameter.

<cfhttp method="Post"

      url="http://www.my_favorite_site.com/search.exe"
      resolveurl="Yes">
   <cfhttpparam type="Formfield"
      name="search"
      value="Macromedia ColdFusion">
</cfhttp>

<cfoutput>
   Response Mime Type: #cfhttp.MimeType#<br>
   Response Length: #len(cfhttp.filecontent)# <br>
   Response Content: <br>
      #htmlcodeformat(cfhttp.filecontent)#<br>
</cfoutput>


Performing file operations with cfftp

The cfftp tag lets you perform tasks on remote servers using File Transfer Protocol (FTP). You can use cfftp to cache connections for batch file transfers when uploading or downloading files.

Note: To use cfftp, the Enable cfftp Tag option must be selected on the Tag Restrictions page of the Basic Security section of the ColdFusion Administrator Security tab.

For server/browser operations, use the cffile, cfcontent, and cfdirectory tags.

Using cfftp involves two major types of operations: connecting, and transferring files. The FTP protocol also provides commands for listing directories and performing other operations. For a complete list of attributes that support FTP operations and additional details on using the cfftp tag, see the CFML Reference.

To open an FTP connection and retrieve a file listing:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>FTP Test</title>
</head>

<body>
<h1>FTP Test</h1>
<!--- Open ftp connection --->
<cfftp connection="Myftp"
   server="MyServer"
   username="MyUserName"
   password="MyPassword"
   action="Open"
   stoponerror="Yes">

<!--- Get the current directory name. --->
<cfftp connection=Myftp
   action="GetCurrentDir"
   stoponerror="Yes">

<!--- output directory name --->
<cfoutput>
   The current directory is:  #cfftp.returnvalue#<p>
</cfoutput>

<!--- Get a listing of the directory. --->
<cfftp connection=Myftp
   action="listdir"
   directory="#cfftp.returnvalue#"
   name="dirlist"
   stoponerror="Yes">
<!--- Close the connection.--->
<cfftp action="close" connection="Myftp">
<p>Did the connection close successfully?
   <cfoutput>#cfftp.succeeded#</cfoutput></p>

<!--- output dirlist results --->
<hr>
<p>FTP Directory Listing:</p>

<cftable query="dirlist" colheaders="yes" htmltable>
   <cfcol header="<B>Name</b>" TEXT="#name#">
   <cfcol header="<B>Path</b>" TEXT="#path#">
   <cfcol header="<B>URL</b>" TEXT="#url#">
   <cfcol header="<B>Length</b>" TEXT="#length#">
   <cfcol header="<B>LastModified</b>"
   TEXT="#DateFormat(lastmodified)#">
   <cfcol header="<B>IsDirectory</b>"
      TEXT="#isdirectory#">
</cftable>
  2. Change MyServer to the name of a server for which you have FTP permission.
  3. Change MyUserName and MyPassword to a valid username and password.

    4. To establish an anonymous connection, enter “anonymous” as the username and an e-mail address (by convention) for the password.

  4. Save the file as ftp_connect.cfm in the myapps directory under your web_root and view it in the web browser.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cfftp connection="Myftp"
   server="MyServer"
   username="MyUserName"
   password="MyPassword"
   action="Open"
   stoponerror="Yes">
Open an FTP connection to the MyServer server and log on as MyUserName. If an error occurs, stop processing and display an error. You can use this connection in other cfftp tags by specifying the Myftp connection.
<cfftp connection=Myftp
   action="GetCurrentDir"
   stoponerror="Yes">
<cfoutput>
   The current directory is:
#cfftp.returnvalue#<p>
</cfoutput>
Use the Myftp connection to get the name of the current directory; stop processing if an error occurs.
Display the current directory.
<cfftp connection=Myftp
   action="ListDir"
   directory="#cfftp.returnvalue#"
   name="dirlist"
   stoponerror="Yes">
Use the Myftp connection to get a directory listing. Use the value returned by the last cfftp call (the current directory of the connection) to specify the directory to list. Save the results in a variable named dirlist (a query object). Stop processing if there is an error.
<cfftp action="close" connection="Myftp">
<p>Did the connection close successfully?
   <cfoutput>#cfftp.succeeded#</cfoutput></p>
Close the connection, and do not stop processing if the operation fails (because you can still use the results). Instead, display the value of the cfftp.succeeded variable, which is Yes if the connection is closed, and No if the operation failed.
<cftable query="dirlist"       colheaders="yes"
htmltable>
  <cfcol header="<B>Name</b>"
    TEXT="#name#">
  <cfcol header="<B>Path</b>"
    TEXT="#path#">
  <cfcol header="<B>URL</b>"
    TEXT="#url#">
  <cfcol header="<B>Length</b>"
    TEXT="#length#">
  <cfcol header="<B>LastModified</b>"
       TEXT="#DateFormat(lastmodified)#">
  <cfcol header="<B>IsDirectory</b>"
    TEXT="#isdirectory#">
</cftable>
Display a table with the results of the ListDir FTP command.

After you establish a connection with cfftp, you can reuse the connection to perform additional FTP operations until either you or the server closes the connection. When you access an already-active FTP connection, you do not need to re-specify the username, password, or server. In this case, make sure that when you use frames, only one frame uses the connection object.

Note: For a single simple FTP operation, such as GetFile or PutFile, you do not need to establish a connection. Specify all the necessary login information, including the server and any login and password, in the single cfftp request.


Caching connections across multiple pages

The FTP connection established by cfftp is maintained only in the current page unless you explicitly assign the connection to a variable with Application or Session scope.

Assigning a cfftp connection to an Application variable could cause problems, since multiple users could access the same connection object at the same time. Creating a Session variable for a cfftp connection makes more sense, because the connection is available to only one client and does not last past the end of the session.


Example: Caching a connection

<cflock scope="Session" timeout=10>
<cfftp action="Open"
   username="anonymous"
   password="me@home.com"
   server="ftp.eclipse.com"
   connection="Session.myconnection">
</cflock>

In this example, the connection cache remains available to other pages within the current session. You must enable Session variables in your application for this approach to work, and you must lock code that uses Session variables. For more information on locking, see Using Persistent Data and Locking.

Note: Changing a connection’s characteristics, such the retrycount or timeout values, might require you to re-establish the connection.


Connection actions and attributes

The following table shows the available cfftp actions and the attributes they require when you use a named (that is, cached) connection. If you do not specify an existing connection name, you must specify the username, password, and server attributes.

Action | Attributes | Action | Attributes
Open | none | Rename | existing new
Close | none | Remove | server item
ChangeDir | directory | GetCurrentDir | none
CreateDir | directory | GetCurrentURL | none
ListDir | name directory | ExistsDir | directory
RemoveDir | directory | ExistsFile | remotefile
GetFile | localfile remotefile | Exists | item
PutFile | localfile remotefile |  |

Previous


Managing Files on the Server

The cffile, cfdirectory, and cfcontent tags handle browser and server file management tasks, such as uploading files from a client to the web server, viewing directory information, and changing the content type that is sent to the web browser. To perform server-to-server operations, use the cfftp tag, described in Performing file operations with cfftp.

Contents
  • About file management
  • Using cffile
  • Using cfdirectory
  • Using cfcontent
Next


About file management

ColdFusion lets you access and manage the files and directories on your ColdFusion server. The cffile tag has several attributes for moving, copying, deleting, and renaming files. You use the cfdirectory tag to list, create, delete, and rename directories. The cfcontent tag lets you define the MIME (Multipurpose Internet Mail Extensions) content type that returns to the web browser.


Using cffile

You can use the cffile tag to work with files on the server in several ways:

  • Upload files from a client to the web server using an HTML form
  • Move, rename, copy, or delete files on the server
  • Read, write, or append to text files on the server

You use the action attribute to specify any of the following file actions: upload, move, rename, copy, delete, read, readBinary, write, and append. The required attributes depend on the action specified. For example, if action="write", ColdFusion expects the attributes associated with writing a text file.

Note: Consider the security and logical structure of directories on the server before allowing users access to them. You can disable the cffile tag in the ColdFusion Administrator. Also, to access files that are not located on the local ColdFusion Server system, ColdFusion services must run using an account with permission to access the remote files and directories.


Uploading files

File uploading requires that you create two files:

  • An HTML form to specify file upload information
  • An action page containing the file upload code

The following procedures describe how to create these files.

To create an HTML file to specify file upload information:

  1. Create a ColdFusion page with the following content:
    2. <head><title>Specify File to Upload</title></head>
<body>
<h2>Specify File to Upload</h2>
<!--- the action attribute is the name of the action page --->
<form action="uploadfileaction.cfm"
      enctype="multipart/form-data"
      method="post">
   <p>Enter the complete path and filename of the file to upload:
   <input type="file"
         name="FiletoUpload"
         size="45">
   </p>
   <input    type="submit"
         value="Upload">
</form>
</body>
  2. Save the file as uploadfileform.cfm in the myapps directory under your web_root and view it in the browser:

    3. This is a picture of the feature being described.

Note: The form will not work until you write an action page for it,. This is the next procedure.


Reviewing the code

The following table describes the code and its function:

Code
Description
<form action="uploadfileaction.cfm"
   enctype="multipart/form-data"
   method="post">
Create a form that contains file selection fields for upload by the user. The action attribute value specifies the ColdFusion template that will process the submitted form. The enctype attribute value tells the server that the form submission contains an uploaded file. The method attribute is set to post to submit a ColdFusion form.
<input type="file"
   name="FiletoUpload"
   size="45">
Allow the user to specify the file to upload. The file type instructs the browser to prepare to read and transmit a file from the user's system to your server. It automatically includes a Browse button to allow the user to look for the file instead of manually entering the entire path and filename.

The user can enter a file path or browse the system and select a file to send.

  1. Create a ColdFusion page with the following content:
    2. <html>
<head> <title>Upload File</title> </head>
<body>
<h2>Upload File</h2>

<cffile action="upload"
      destination="c:\temp\"
      nameConflict="overwrite"
      fileField="Form.FiletoUpload">

<cfoutput>
You uploaded #cffile.ClientFileName#.#cffile.ClientFileExt#
         successfully to #cffile.ServerDirectory#.
</cfoutput>

</body>
</html>
  2. Change the following line to point to an appropriate location on your server:
    3. destination="c:\temp\"

    Note: This directory must exist on the server.
  3. Save the file as uploadfileaction.cfm in the myapps directory under your web_root.
  4. View uploadfileform.cfm in the browser, enter a file to upload, and submit the form.

    5. The file you specified uploads:

    This is a picture of the feature being described.


Reviewing the code

The following table describes the code and its function:

Code
Description
<cffile action="upload"
Output the name and location of the uploaded file on the client machine.
destination="c:\temp\"
Specify the destination of the file.
nameConflict="overwrite"
If the file already exists, overwrite it.
fileField="Form.FiletoUpload">
Specify the name of the file to upload. Do not enclose the variable in pound signs.
You uploaded #cffile.ClientFileName#.#cffile.
ClientFileExt# successfully to
#cffile.ServerDirectory#.
Inform the user of the file that was uploaded and its destination. For information on cffile scope variables, see Evaluating the results of a file upload.

Note: This example performs no error checking and does not incorporate any security measures. Before deploying an application that performs file uploads, be sure to incorporate both error handling and security. For more information, see Securing Applications and Handling Errors.


Resolving conflicting filenames

When you save a file to the server, there is a risk that a file with the same name might already exist. To resolve this problem, assign one of these values to the nameConflict attribute of the cffile tag:

  • Error (default) ColdFusion stops processing the page and returns an error. The file is not saved.
  • Skip Allows custom behavior based on file properties. Neither saves the file nor returns an error.
  • Overwrite Overwrites a file that has the same name as the uploaded file.
  • MakeUnique Generates a unique filename for the uploaded file. The name is stored in the file object variables serverFile and serverFileName. You can use this variable to record the name used when the file was saved. The unique name might not resemble the attempted name. For more information on file upload status variables, see Evaluating the results of a file upload.


Controlling the type of file uploaded

For some applications, you might want to restrict the type of file that is uploaded. For example, you might not want to accept graphic files in a document library.

You use the accept attribute to restrict the type of file that you allow in an upload. When an accept qualifier is present, the uploaded file’s MIME content type must match the criteria specified or an error occurs. The accept attribute takes a comma-separated list of MIME data names, optionally with wildcards.

A file’s MIME type is determined by the browser. Common types, such as image/gif and text/plain, are registered in the browser.

Note: Modern versions of Internet Explorer and Netscape support MIME type associations. Other browsers and older versions may ignore these associations.

ColdFusion saves any uploaded file if you omit the accept attribute or specify "*/*". You can restrict the file types, as demonstrated in the following examples.

This cffile tag saves an image file only if it is in the GIF format:

<cffile action="Upload"
   fileField="Form.FiletoUpload"
   destination="c:\uploads\"
   nameConflict="Overwrite"
   accept="image/gif">

This cffile tag saves an image file only if it is in GIF or JPEG format:

<cffile action="Upload"
   fileField="Form.FiletoUpload"
   destination="c:\uploads\"
   nameConflict="Overwrite"
   accept="image/gif, image/jpeg">

Note: If you receive an error similar to "The MIME type of the uploaded file (image/pjpeg) was not accepted by the server", then enter accept="image/pjpeg" to accept JPEG files.

This cffile tag saves any image file, regardless of the format:

<cffile action="Upload"
   fileField="Form.FiletoUpload"
   destination="c:\uploads\"
   nameConflict="Overwrite"
   accept="image/*">


Setting file and directory attributes

In Windows, you specify file attributes using the cffile attributes attribute. In UNIX, you specify file or directory permissions using the mode attribute of the cffile or cfdirectory tag.


Windows

In Windows, you can set the following file attributes:

  • Archive
  • Hidden
  • Normal
  • ReadOnly
  • System

To specify several attributes in CFML, use a comma-separated list for the attributes attribute; for example, attributes="ReadOnly,Archive". If you do not use attributes, the file’s existing attributes are maintained. If you specify any other attributes in addition to Normal, the additional attribute overrides the Normal setting.


UNIX

In UNIX, you can individually set permissions on files and directories for each of three types of users--owner, group, and other. You use a number for each user type. This number is the sum of the numbers for the individual permissions allowed. Values for the mode attribute correspond to octal values for the UNIX chmod command:

  • 4 = read
  • 2 = write
  • 1 = execute

You enter permissions values in the mode attribute for each type of user: owner, group, and other in that order. For example, use the following code to assign read permissions for everyone:

mode=444

To give a file or directory owner read/write/execute permissions and read only permissions for everyone else:

mode=744


Evaluating the results of a file upload

After a file upload is completed, you can retrieve status information using file upload status variables. This status information includes data about the file, such as its name and the directory where it was saved.

You can access file upload status variables using dot notation, using either file.varname or cffile.varname. Although you can use either the File or cffile prefix for file upload status variables, cffile is preferred; for example, cffile.ClientDirectory. The File prefix is retained for backward compatibility.

Note: File status variables are read-only. They are set to the results of the most recent cffile operation. If two cffile tags execute, the results of the first are overwritten by the subsequent cffile operation.

The following table describes the file upload status variables that are available after an upload:

Variable | Description
attemptedServerFile | Initial name that ColdFusion uses when attempting to save a file; for example, myfile.txt. (see Resolving conflicting filenames).
clientDirectory | Directory on the client’s system from which the file was uploaded.
clientFile | Full name of the source file on the client’s system with the file extension; for example, myfile.txt.
clientFileName | Name of the source file on the client’s system without an extension; for example, myfile.
clientFileExt | Extension of the source file on the client’s system without a period; for example, txt (not .txt).
contentType | MIME content type of the saved file; for example, image for image/gif.
contentSubType | MIME content subtype of the saved file; for example, gif for image/gif.
dateLastAccessed | Date that the uploaded file was last accessed.
fileExisted | Indicates (Yes or No) whether the file already existed with the same path.
fileSize | Size of the uploaded file.
fileWasAppended | Indicates (Yes or No) whether ColdFusion appended the uploaded file to an existing file.
fileWasOverwritten | Indicates (Yes or No) whether ColdFusion overwrote a file.
fileWasRenamed | Indicates (Yes or No) whether the uploaded file was renamed to avoid a name conflict.
fileWasSaved | Indicates (Yes or No) whether ColdFusion saved the uploaded file.
oldFileSize | Size of the file that was overwritten in the file upload operation. Empty if no file was overwritten.
serverDirectory | Directory where the file was saved on the server.
serverFile | Full name of the file saved on the server with the file extension; for example, myfile.txt.
serverFileName | Name of the file saved on the server without an extension; for example, myfile.
serverFileExt | Extension of the file saved on the server without a period; for example, txt (not .txt).
timeCreated | Date and time the uploaded file was created.
timeLastModified | Date and time of the last modification to the uploaded file.


Moving, renaming, copying, and deleting server files

With cffile, you can create application pages to manage files on your web server. You can use the tag to move files from one directory to another, rename files, copy a file, or delete a file.

The examples in the following table show static values for many of the attributes. However, the value of all or part of any attribute in a cffile tag can be a dynamic parameter.

Action
Example code
Move a file
<cffile action="move"
   source="c:\files\upload\KeyMemo.doc"
   destination="c:\files\memo\">
Rename a file
<cffile action="rename"
   source="c:\files\memo\KeyMemo.doc"
   destination="c:\files\memo\OldMemo.doc">
Copy a file
<cffile action="copy"
   source="c:\files\upload\KeyMemo.doc"
   destination="c:\files\backup\">
Delete a file
<cffile action="delete"
   file="c:\files\upload\oldfile.txt">

This example sets the archive bit for the uploaded file:

<cffile action="Copy"
   source="c:\files\upload\keymemo.doc"
   destination="c:\files\backup\"
   attributes="Archive">

Note: Ensure you include the trailing slash (\) when you specify the destination directory. Otherwise, ColdFusion treats the last element in the pathname as a filename. This only applies to copy actions.


Reading, writing, and appending to a text file

In addition to managing files on the server, you can use cffile to read, create, and modify text files. As a result, you can do the following things:

  • Create log files. (You can also use cflog to create and write to log files.)
  • Generate static HTML documents.
  • Use text files to store information that can be incorporated into web pages.


Reading a text file

You can use cffile to read an existing text file. The file is read into a local variable that you can use anywhere in the application page. For example, you could read a text file and then insert its contents into a database, or you could read a text file and then use one of the string replacement functions to modify the contents.

To read a text file:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Read a Text File</title>
</head>

<body>
Ready to read the file:<br>
<cffile action="read"
   file="C:\inetpub\wwwroot\mine\message.txt"
   variable="Message">

<cfoutput>
   #Message#
</cfoutput>
</body>
</html>
  2. Replace C:\inetpub\wwwroot\mine\message.txt with the location and name of a text file on the server.
  3. Save the file as readtext.cfm in the myapps directory under your web_root and view it in the browser:

    4. This is a picture of the feature being described.


Writing a text file on the server

You can use cffile to write a text file based on dynamic content. For example, you could create static HTML files or log actions in a text file.

To create a form in to capture data for a text file:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Put Information into a Text File</title>
</head>

<body>
<h2>Put Information into a Text File</h2>

<form action="writetextfileaction.cfm" method="Post">
   <p>Enter your name: <input type="text" name="Name" size="25"></p>
   <p>Enter the name of the file: <input type="text" name="FileName"
size="25">.txt</p>
   <p>Enter your message:
   <textarea name="message"cols=45 rows=6></textarea>
   </p>
   <input type="submit" name="submit" value="Submit">
</form>
</body>
</html>
  2. Save the file as writetextfileform.cfm in the myapps directory under your web_root.

Note: The form will not work until you write an action page for it. This is the next procedure.

To write a text file:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>Write a Text File</title>
</head>
<body>
<cffile action="write"
   file="C:\inetpub\wwwroot\mine\#Form.FileName#.txt"
   output="Created By: #Form.Name#
#Form.Message# ">
</body>
</html>
  2. Modify the path C:\inetpub\wwwroot\mine\ to point to a path on your server.
  3. Save the file as writetextfileaction.cfm in the myapps directory under your web_root.
  4. View the file writetextfileform.cfm in the browser, enter values, and submit the form.

    5. This is a picture of the feature being described.

    The text file is written to the location you specified. If the file already exists, it is replaced.


Appending a text file

You can use cffile to append additional text to the end of a text file; for example, when you create log files.

To append a text file:

  1. Open the writetextfileaction.cfm file in ColdFusion Studio.
  2. Change the value for the action attribute from write to append so that the file appears as follows:
    3. <html>
<head>
   <title>Append a Text File</title>
</head>
<body>
<cffile action="append"
   file="C:\inetpub\wwwroot\mine\message.txt"
   output="Appended By: #Form.Name#">
</body>
</html>
  3. Save the file as writetextfileaction.cfm in the myapps directory under your web_root.
  4. View the file in the browser, enter values, and submit the form.

    5. The appended information displays at the end of the text file.


Using cfdirectory

Use the cfdirectory tag to return file information from a specified directory and to create, delete, and rename directories.

As with cffile, you can disable cfdirectory processing in the ColdFusion Administrator. For details on the syntax of this tag, see the CFML Reference.


Returning file information

When you use the action="list" attribute setting, cfdirectory returns a query object as specified in the name attribute. The name attribute is required when you use the action="list" attribute setting. This query object contains five result columns that you can reference in a cfoutput tag, using the name attribute:

  • name Directory entry name.
  • size Directory entry size.
  • type File type: File or Dir.
  • dateLastModified Date an entry was last modified.
  • attributes (Windows only) File attributes, if applicable.
  • mode (UNIX only) The octal value representing the permissions setting for the specified directory.

Note: ColdFusion supports the ReadOnly and Hidden values for the attributes attribute for cfdirectory sorting.

Note that depending on whether your server is on a UNIX system or a Windows system, either the Attributes column or the Mode column is empty. Also, you can specify a filename in the filter attribute to get information on a single file.

The following procedure describes how to create a ColdFusion page in which to view directory information.

To view directory information:

  1. Create a ColdFusion page with the following content:
    2. <html>
<head>
   <title>List Directory Information</title>
</head>

<body>
<h3>List Directory Information</h3>
<cfdirectory
   directory="c:\inetpub\wwwroot\mine"
   name="mydirectory"
   sort="size ASC, name DESC, datelastmodified">

<table cellspacing=1 cellpadding=10>
<tr>
   <th>Name</th>
   <th>Size</th>
   <th>Type</th>
   <th>Modified</th>
   <th>Attributes</th>
   <th>Mode</th>
</tr>
<cfoutput query="mydirectory">
<tr>
   <td>#mydirectory.name#</td>
   <td>#mydirectory.size#</td>
   <td>#mydirectory.type#</td>
   <td>#mydirectory.dateLastModified#</td>
   <td>#mydirectory.attributes#</td>
   <td>#mydirectory.mode#</td>
</tr>
</cfoutput>
</table>

</body>
</html>
  2. Modify the path C:\inetpub\wwwroot\mine so that it points to a directory on your server.
  3. Save the file as directoryinfo.cfm in the myapps directory under your web_root and view it in the browser:

    4. This is a picture of the feature being described.


Using cfcontent

The cfcontent tag downloads files from the server to the client. You can use this tag to set the MIME type of the content returned by a ColdFusion page and, optionally, define the filename of a file to be downloaded by the current page. By default, ColdFusion returns a MIME content type of text/html so that a web browser renders your template text as a web page.

As with cffile, and cfdirectory, you can disable cfcontent processing in the ColdFusion Administrator.


About MIME types

A MIME type is a label that identifies the contents of a file. the browser uses the MIME type specification to determine how to interact with the file. For example, the browser could open a spreadsheet program when it encounters a file identified by its MIME content type as a spreadsheet file.

A MIME content type consists of "type/subtype" format. The following are common MIME content types:

  • text/html
  • image/gif
  • application/pdf


Changing the MIME content type with cfcontent

You use the cfcontent tag to change the MIME content type that returns to the browser along with the content generated from your ColdFusion page.

The cfcontent tag has one required attribute, type, which defines the MIME content type returned by the current page.

To change the MIME content type with cfcontent:

  1. Create an HTML page with the following content:
    2. <h1>cfcontent_message.htm</h1>

<p>This is a <em>test message</em> written in HTML.</p>
<p>This is the <em>second paragraph</em> of the test message.
As you might expect, it is also written in HTML.</p>
  2. Save the file as cfcontent_message.htm in the myapps directory under your web_root.

    3. This HTML file will be called by the ColdFusion file that you write in steps 3 through 7.

  3. Create a ColdFusion page with the following content:
    4. <html>
<head>
<title>cfcontent Example</title>
</head>

<body>
<h3>cfcontent Example</h3>

<cfcontent
   type = "text/html"
   file = "C:\CFusionMX\wwwroot\myapps\cfcontent_message.htm"
   deleteFile = "No">
</body>
</html>
  4. If necessary, edit the file = line to point to your myapps directory.
  5. Save the file as cfcontent.cfm in the myapps directory under your web_root and view it in the browser.

    6. The text of the called file (cfcontent_message.htm) displays as normal HTML:

    This is a picture of the feature being described.

  6. In cfcontent.cfm, change type = "text/html" to type = "text/plain".
  7. Save the file and view it in the browser (refresh it if necessary).

    8. The text displays as unformatted text, in which HTML tags are treated as text:

    This is a picture of the feature being described.

The following example shows how the cfcontent tag can create an Excel spreadsheet that contains your data.

To create an Excel spreadsheet with cfcontent:

  1. Create a ColdFusion page with the following content:
    2. <!--- use cfsetting to block output of HTML
outside of cfoutput tags --->
<cfsetting enablecfoutputonly="Yes">

<!--- get employee info --->
<cfquery name="GetEmps" datasource="CompanyInfo">
   SELECT * FROM Employees
</cfquery>

<!--- set vars for special chars --->
<cfset TabChar = Chr(9)>
<cfset NewLine = Chr(13) & Chr(10)>
<!--- set content type to invoke Excel --->
<cfcontent type="application/msexcel">

<!--- suggest default name for XLS file --->
<!--- use "Content-Disposition" in cfheader for
Internet Explorer  --->
<cfheader name="Content-Disposition" value="filename=Employees.xls">
 <!--- output data using cfloop & cfoutput --->
<cfloop query="GetEmps">
   <cfoutput>#Employee_ID##TabChar##LastName#
   #TabChar##FirstName##TabChar##Salary##NewLine#</cfoutput>
</cfloop>
  2. Save the file as employees_to_excel.cfm in the myapps directory under your web_root and view it in the browser.

    3. The data appears in an Excel spreadsheet:

    This is a picture of the feature being described.

Previous


About This Book

Using Server-Side ActionScript in ColdFusion MX describes how to access ColdFusion services using ActionScript, the scripting language associated with Macromedia Flash.

Contents
  • Developer resources
  • About ColdFusion documentation
  • Getting answers
  • Contacting Macromedia
Next


Developer resources

Macromedia, Inc. is committed to setting the standard for customer support in developer education, technical support, and professional services. The Macromedia website is designed to give you quick access to the entire range of online resources. The following table shows the locations of these resources:

Resource | Description | URL
Macromedia website | General information about Macromedia products and services | http://www.macromedia.com
Information on ColdFusion | Detailed product information for ColdFusion and related topics | http://www.macromedia.com/coldfusion
Macromedia ColdFusion Support Center | Professional support programs that Macromedia offers | http://www.macromedia.com/support/coldfusion
ColdFusion Online Forum | Access to experienced ColdFusion developers through participation in the Online Forums, where you can post messages and read replies on many subjects relating to ColdFusion | http://webforums.macromedia.com/coldfusion/
Installation Support | Support for installation-related issues for all Macromedia products | http://www.macromedia.com/support/email/isupport
Training | Information about classes, on-site training, and online courses offered by Macromedia | http://www.macromedia.com/support/training
Developer Resources | All the resources that you need to stay on the cutting edge of ColdFusion development, including online discussion groups, Knowledge Base, technical papers, and more | http://www.macromedia.com/desdev/developer/
Reference Desk | Development tips, articles, documentation, and white papers | http://www.macromedia.com/v1/developer/TechnologyReference/index.cfm
Macromedia Alliance | Connection with the growing network of solution providers, application developers, resellers, and hosting services creating solutions with ColdFusion | http://www.macromedia.com/partners/


Printed and online documentation set

The ColdFusion documentation set consists of the following titles:

Book | Description
Installing ColdFusion Server | Describes system installation and basic configuration for Windows NT, Windows 2000, Solaris, Linux, and HP-UX.
Administering ColdFusion Server | Describes how to connect your data sources to the ColdFusion Server, configure security for your applications, and how to use ClusterCATS to manage scalability, clustering, and load-balancing for your site.
Developing ColdFusion Applications | Describes how to develop your dynamic web applications, including retrieving and updating your data, and using structures and forms.
Getting Started with ColdFusion Applications | Contains an overview of ColdFusion features and application development procedures. Includes a tutorial that guides you through the process of developing a sample ColdFusion application.
Using Server-Side ActionScript in ColdFusion MX | Describes how Macromedia Flash movies executing on a client browser can call ActionScript code running on the ColdFusion Server. Includes examples of server-side ActionScript and a syntax guide for developing ActionScript pages on the server.
Migrating from ColdFusion 5 | Describes how to migrate a ColdFusion 5 application to ColdFusion MX. This book describes the code compatibility analyzer that evaluates your ColdFusion 5 code to determine any incompatibilities within it.
CFML Reference | Provides descriptions, syntax, usage, and code examples for all ColdFusion tags, functions, and variables.
CFML Quick Reference | A brief guide that shows the syntax of ColdFusion tags, functions, and variables.
Working with Verity Tools | Describes Verity search tools and utilities that you can use for configuring the Verity K2 Server search engine, as well as creating, managing, and troubleshooting Verity collections.


Introduction

Macromedia ColdFusion Server MX includes the Macromedia Flash Remoting service, a module that lets Macromedia Flash developers create server-side ActionScript. These ActionScripts can directly access ColdFusion query and HTTP features through two new ActionScript functions: CF.query and CF.http. This chapter introduces the concepts and basic requirements for creating server-side ActionScript for ColdFusion MX.

Contents
  • About server-side ActionScript
  • More about server-side ActionScript
  • What to do next
Next


About server-side ActionScript

Macromedia ColdFusion MX includes a module called the Macromedia Flash Remoting service that acts as a broker for interactions between Macromedia Flash MX and ColdFusion MX. In addition to support for a range of object types, Flash Remoting also lets you reference an ActionScript file that lives on a ColdFusion server.

The ability to create server-side ActionScript provides a familiar way for Flash developers to access ColdFusion resources without having to learn CFML (ColdFusion Markup Language). One benefit of this feature is that it lets you partition data-intensive operations on the server, while limiting the amount of network transactions necessary to get data from server to client.

In addition, this feature lets you logically separate the Flash presentation elements of your applications from the business logic. Now you have the option of creating ActionScript files that reside on the server to partition this processing away from your client applications.

You have a very simple interface for building queries using server-side ActionScript, and an equally simple interface for invoking these queries from your client-side ActionScript.


Client-side ActionScript requirements

On the client side, you only need a small piece of code that establishes a connection to the Flash Remoting service and references the server-side ActionScript you want to use.

For example (note embedded comments):

// This #include is needed to connect to the Flash Remoting service
#include "NetServices.as"

// This line determines where Flash MX should look for the Flash Remoting service.
// Ordinarily, you enter the URL to your ColdFusion server.
// Port 8500 is the Flash Remoting service default.
NetServices.setDefaultGatewayUrl("http://mycfserver:8500");

// With the Flash Remoting service URL defined, now you can create a connection.
gatewayConnnection = NetServices.createGatewayConnection();

// Here’s where you reference the server-side ActionScript.
// In this case the stockquotes script file lives in the web root of the
// ColdFusion server identified previously. If it lived in a subdirectory
// of the web root called "mydir," you would reference it
// as "mydir.stockquotes".
stockService = gatewayConnnection.getService("stockquotes", this);

// This line invokes the getQuotes() method defined in the stockquotes
// server-side ActionScript.
stockService.getQuotes("macr");

// Once the record set is returned, you handle the results.
// This part is up to you.
function getQuotes_Result ( result )
{
   // Do something with results
}

Note: The two new server-side ActionScript functions, CF.query and CF.http, are not supported in client-side ActionScript.


Server-side requirements

The option of creating ActionScript that executes on the server helps leverage your knowledge of ActionScript, while providing direct access to ColdFusion query and HTTP features. The CF.query and CF.http ActionScript functions let you perform ColdFusion HTTP and query operations:.

Note: On the server side, ActionScript files use the extension .asr.

For example, the following server-side ActionScript builds on the client-side code shown previously:

// Filename: stockquotes.asr
// Here is the getQuotes method invoked in the client-side ActionScript.
// It accepts a single stock quote symbol argument.
function getQuotes(symbol)
{
   // Query some provider for the specified stock quote and return the
   // results. In this case, the getQuotesFromProvider method is
   // defined elsewhere in this ActionScript.
   data = getQuotesFromProvider(symbol);
   // Now return the data to the client.
   // Note that this example does not include any of the error checking
   // logic you would normally use prior to returning the data.
   return data;
}

The getQuotes function conducts the stock quote request and returns the results of the request to the client as a RecordSet object.


Software requirements

To use server-side ActionScripts, you must have the following software installed:

  • Macromedia Flash MX
  • Macromedia ColdFusion MX
  • Flash Remoting Components

For more information about these products, go to www.macromedia.com.


More about server-side ActionScript

The ability to create server-side ActionScript provides a familiar way for Flash developers to access ColdFusion resources without having to learn CFML.

Through the Flash Remoting service, Flash developers can leverage their knowledge of ActionScript to access ColdFusion query and HTTP features. The only new things you need to learn to make use of this feature are the use of two new ActionScript functions that let you perform ColdFusion HTTP and query operations, and a few lines of setup code on the client side.

This is a feature that lets you create data-intensive Flash-based applications. Creating ActionScript files that reside on the server helps the business logic part of your application from the user interface.


Location of server-side ActionScript files

You can place ActionScript files (*.asr) on the server anywhere below the web server’s root directory. To specify subdirectories of the web root or a virtual directory, use package dot notation. For example, in the following assignment code, the stockquotes.asr file is located in the mydir/stock/ directory:

stockService = gatewayConnnection.getService("mydir.stock.stockquotes", this);

You can also point to virtual mappings, such as, cfsuite.asr.stock.stockquotes where cfsuite is a virtual mapping and asr.stock is subdirectories of that mapping.


Benefits

Server-side ActionScript lets your ActionScript engineers use their knowledge of ActionScript to write code for the backend of their Flash applications, which can mean more meaningful levels of interactivity for your users. Your Flash applications can share a library of server-side ActionScript functions, which means you can define functions that are specifically tailored to your own business.

You could, for example, create a server-side ActionScript that defines a whole library of SQL query methods. With these query methods defined on the server-side, your Flash designers only have to invoke the specific query function they want to return data to their Flash MX movies. They do not have to write any SQL, and they do not have to create a new query every time they need to retrieve data from a ColdFusion data source. It is a way of creating reusable queries that your entire Flash design team can use.

Coding the ColdFusion query and HTTP operations in ActionScript is very straightforward. The CF.query and CF.http functions provide a well-defined interface for building SQL queries and HTTP operations that is based on the legendary simplicity of ColdFusion.

For example, the following is a typical server-side ActionScript function definition that returns query data:

// This function shows a basic CF.query operation using only
// arguments for data source name and for SQL.
function basicQuery()
{
   mydata = CF.query({datasource:"customers",
      sql:"SELECT * FROM myTable"});

   return mydata;

}


What to do next

If you are already familiar with ActionScript, you only need to know a few things to get started:

  • How to establish a connection with the Flash Remoting service using client-side ActionScript. For details, see Connecting to the Flash Remoting service
  • How to reference server-side ActionScripts and methods. For details, refer to Calling server-side ActionScript functions
  • How to code the server-side CF.query and CF.http functions. For details, see ColdFusion ActionScript Functions.

The following table shows where to find more information about using ActionScript with ColdFusion MX:

For more information about | See
ActionScript | Macromedia Flash MX documentation, and www.macromedia.com
Coding client-side and servier-side ActionScript | ColdFusion ActionScript Functions
Writing query functions using server-side ActionScript | Using the CF.query Function
Writing HTTp functions using server-side ActionScript | Using the CF.http Function
Previous


Connecting to the Flash Remoting Service

This chapter describes how to establish a connection to the Macromedia Flash Remoting service, and includes other programming details about referencing server-side ActionScript.

Contents
  • Connecting to the Flash Remoting service
  • Calling server-side ActionScript functions
  • Using the function results in ActionScript
  • Global and request scope objects
Next


Connecting to the Flash Remoting service

Before you can use functions defined in your server-side ActionScript, you must first perform several initial set up tasks.

First, you connect the Macromedia Flash movie to the server-side Flash Remoting service. The following steps create a Flash Remoting service connection:

  1. Include NetServices.as in your Flash movie.
  2. Specify the default Flash Remoting service URL and create a connection to the service.

See the following sections for more details:

  • Including the necessary ActionScript classes
  • Establishing a connection to the Flash Remoting service

After you perform this setup, you can use the functions defined in your server-side ActionScript.


Including the necessary ActionScript classes

You must include a series of ActionScript classes in the first frame of the Flash movie that will be using server-side ActionScript functions. The following command includes the NetServices class:

#include "NetServices.as"

The following command includes the NetDebug class:

#include "NetDebug.as"

The NetServices include statement is required for server-side ActionScript. The NetDebug include statement is optional.


Establishing a connection to the Flash Remoting service

The Flash Remoting service serves as a broker for calls to server-side ActionScripts.

To use server-side ActionScript:

  1. Identify the Flash Remoting service URL as an argument in the NetServices.setDefaultGatewayUrl function; for example:
    2. NetServices.setDefaultGatewayURL("http://localhost:8500/flashservices")

You must specify a ColdFusion MX Server hostname. The default port number for the Flash Remoting service is 8500.
  2. Create the gateway connection using the NetServices.createGatewayConnection function; for example:
    3. gatewayConnection = NetServices.createGatewayConnection();


Calling server-side ActionScript functions

After you connect to the Flash Remoting service, you call functions that are defined in your server-side ActionScript, and return results.

To call a functions:

  1. Create an instance of the server-side ActionScript using the getService function. This function instantiates the server-side ActionScript as an object to be used on the client side.
  2. Call a function defined in your server-side ActionScript object.
  3. Handle the function results in ActionScript.

For more information, see the following sections:

  • Creating an instance of the server-side ActionScript
  • Calling a server-side ActionScript function
  • Using the function results in ActionScript


Creating an instance of the server-side ActionScript

To access the server-side ActionScript, first you must create an instance of it so it can be invoked in your client-side ActionScript. To create an instance of your server-side ActionScript, use the gatewayConnection.getService function; for example:

albumService = gatewayConnection.getService("recordsettest", this)

In the example, recordsettest represents the name of the server-side ActionScript file, without the file extension .asr.


Calling a server-side ActionScript function

To use the functions in a server-side ActionScript, you use dot notation to specify the object name name followed by the function name; for example:

albumService.getAlbum("The Color And The Shape", "1999");

In the example, albumService is the instance of the server-side ActionScript and getAlbum is a function that passes two arguments, "The Color and The Shape" and "1999".

Note: Arguments must occur in the order defined in the function declaration.


Using the function results in ActionScript

To use the results returned by server-side ActionScript, you must create a corresponding results function, which is a function defined specifically to handle the results returned by a function that calls a server-side ActionScript. The results function uses a special naming convention that ties it to the function that calls the server-side ActionScript. For example, if you defined a client-side ActionScript function called basicCustomerQuery, you also must create a results function called basicCustomerQuery_result.

The results returned by server-side ActionScript functions differ somewhat depending on whether you are using CF.http or CF.query.

The CF.query function returns a record set, which you manipulate using methods available in the RecordSet ActionScript class object.

The CF.http function returns simple text strings through properties that you reference in your server-side ActionScript.

For more information, see the following sections:

  • Using results returned by the CF.query function
  • Using results returned by the CF.http function


Using results returned by the CF.query function

You access the data returned in a CF.query record set using functions in the RecordSet ActionScript object. Functions in the RecordSet object let you determine how many records are in the record set, what the column names are, and so on. RecordSet functions also let you pull the query data out of the record set. To do so, you reference a specific row number in the record set and use the getItemAt RecordSet function, as in the following example:

// This function populates a Flash text box with data in the first row
// of the record set under the "email" column name.
function selectData_result ( result )
{
   stringOutput.text =  result.getItemAt(0)["email"];
   _root.employeesView.setDataProvider(result);
}

In the example, the column name is referenced in the getItemAt function between square brackets []. The rows returned by the CF.query function are counted starting from one, so the first row is row 0 (zero), the second row is row 1, and so on.

For more information about coding the server-side CF.query function, see Using the CF.query Function.


Using results returned by the CF.http function

The CF.http server-side ActionScript function returns data as simple text. You write server-side functions that reference the properties available in the object returned by the CF.http function. These properties store the file content of the retrieved file, HTTP status codes, the MIME type of the returned file, and so on. On the client side, you create return functions to handle data returned by the CF.http function. You write these functions to handle simple text data.

For more information, see Using the CF.http Function.


Global and request scope objects

Global and request scope objects are implicitly available in all server-side ActionScript. The following table describes these scope objects:

Scope name | Type | Description
config | Global | Initialization information for the server-side ActionScript adapter. Class: javax.servlet.ServletConfig
application | Global | The context for the current web application. The context defines methods that provide, for example, the MIME type of a file that can be used to write to a log file. There is one context per web application. Class: javax.servlet.ServletContext
request | Request | An object containing client request information. The object provides data including parameter name and values, attributes, and an input stream. Class: HttpServletRequest (subtype of javax.servlet.ServletRequest)
response | Request | An object to assist in sending a response to the client. It provides HTTP-specific functionality in sending a response. Do not use the OutputStream or PrintWriter to send data back to the client. Class: HttpServletResponse (subtype of javax.servlet.ServletResponse)

For more information about these scope objects, see the documentation on the javax.servlet class, found at http://java.sun.com.

Previous


Using the CF.query Function

This chapter describes how to retrieve data from a database using the CF.query ActionScript function.

Contents
  • Overview
  • About ColdFusion data sources
  • The CF.query ActionScript function
  • The CF.query record set
  • Building a simple application
Next


Overview

The CF.query function lets you populate Macromedia Flash MX movie elements with data retrieved from a ColdFusion data source.

To pull data into your Flash MX movie from a ColdFusion data source:

  1. Create a server-side ActionScript file that performs queries against a ColdFusion data source.
  2. Write ActionScript code in your Flash MX movie that references your ActionScript file (.asr) on the ColdFusion server.

You create a server-side ActionScript to execute the query and returns the data in a record set to the client--your Flash MX movie. You can use methods in the RecordSet ActionScript object on the client to manipulate data in the record set and present data in your Flash MX movie.

Note: Client-side ActionScript files use the .as extension. Server-side ActionScript files use the .asr extension, for "ActionScript remote."


Publishing dynamic data

The server-side ActionScript feature in ColdFusion Server MX lets you write server-side ActionScript files to perform queries against ColdFusion data sources. You must first understand the following:

  • How to code database queries in the server-side ActionScript file using the CF.query ActionScript function. See CF.query.
  • How to reference the server-side ActionScript file in your Flash MX movie. See Connecting to the Flash Remoting Service.

Using the CF.query function, you can do the following tasks:

  • Create user login interfaces that validate users against a ColdFusion data source.
  • Populate form elements and data grids with data from a ColdFusion data source.
  • Create banners that draw data (such as URLs or image file paths) out of a database.

The CF.query function can retrieve data from any supported ColdFusion data source (see About ColdFusion data sources).


About ColdFusion data sources

Your ColdFusion administrator can help you identify and configure data sources. To create ActionScript files that successfully perform queries on ColdFusion MX data sources, you msut know how the data source is identified by ColdFusion, as well as any other parameters that affect your ability to connect to that database, such as whether a username and password are required to connect. Your ColdFusion administrator can provide this information.

For ColdFusion developers, the term data source can refer to a number of different types of structured data accessible locally or across a network. You can query websites, LDAP servers, POP mail servers, and documents in a variety of formats.

However, for server-side ActionScript, a data source ordinarily means the entry point to a ColdFusion database.

For more detailed information about ColdFusion data sources, see Administering ColdFusion Server in the ColdFusion MX Server documentation.


Accessing ColdFusion data sources using ActionScript

The server-side ActionScript feature in ColdFusion MX provides the ability to return record set data to a Flash MX client from a ColdFusion data source. The ColdFusion data source name and the SQL statement you execute on the data source are both arguments you specify in the CF.query function in the server-side ActionScript.

Typically, your server-side ActionScript handles the interaction with the ColdFusion data source, and returns a record set to the Flash MX client through the Flash Remoting service.

For information about building queries using the CF.query function in server-side ActionScript, see The CF.query ActionScript function.


The CF.query ActionScript function

You use the CF.query in your server-side ActionScript to retrieve data from a ColdFusion data source. This function lets you perform queries against any ColdFusion data source.

Note: CF.query maps closely to the cfquery CFML tag, though it currently supports a subset of the cfquery attributes.

Use the CF.query function to do the following:

  • Identify the data source you want to query.
  • Pass SQL statements to the data source.
  • Pass other optional parameters to the database.

For reference information about the CF.query function, see ColdFusion ActionScript Functions.


CF.query function syntax

You can write the CF.query ActionScript function using either named arguments or positional arguments. The named argument style is more readable than the positional argument style, even though it is more laborious to code CF.query declarations in this way. Although the positional argument style supports a subset of CF.query arguments, it allows a more compact coding style that is more appropriate for simple expressions of the CF.query function.


CF.query named argument syntax

The CF.query function accepts the following named arguments:

// CF.query named argument syntax
CF.query
   ({
      datasource:"data source name",
      sql:"SQL stmts",
      username:"username",
      password:"password",
      maxrows:number,
      timeout:milliseconds
   })

Note: The named argument style requires curly braces {} to surround the function arguments.


CF.query positional argument syntax

The positional argument approach supports a subset of CF.query arguments, but it lets you code in a leaner more efficient style. The schema for the positional argument style is as follows:

// CF.query positional argument syntax
CF.query(datasource, sql);
CF.query(datasource, sql, maxrows);
CF.query(datasource, sql, username, password);
CF.query(datasource, sql, username, password, maxrows);

Note: When using positional arguments, do not use curly braces {}.

For more information about the CF.query function, see CF.query.


The CF.query record set

The CF.query function returns a RecordSet object, which is an instance of the RecordSet class of objects. The RecordSet class provides a wide range of functions for handling record set data.

You use methods in the RecordSet ActionScript class in your client-side ActionScript to scrub, manipulate, mine, filter, sort, or otherwise change data returned in the CF.query record set.

Currently, the following methods are available in the RecordSet class:

Method | Description
addItem | Appends a record to the end of the specified RecordSet
addItemAt | Inserts a record at the specified index
addView | Requests notification of changes in a RecordSet object’s state
filter | Creates a new RecordSet object that contains selected records from the original RecordSet object
getColumnNames | Returns the names of all the columns of the RecordSet
getItemAt | Retrieves a record from a RecordSet object
getItemID | Gets the unique ID corrresponding to a record
getLength | Returns the total number of records in a RecordSet object
getNumberAvailable | Returns the number of records that have been downloaded from the server
isFullyPopulated | Determines whether a RecordSet object can be edited or manipulated
isLocal | Determines whether a RecordSet object is local or server-associated
removeAll | Removes all records from the RecordSet object
removeItemAt | Removes a specified record
replaceItemAt | Replaces the entire contents of a record
setDeliveryMode | Changes the delivery mode of a server-associated record set
setField | Replaces one field of a record with a new value
sort | Sorts all records by a specified compare function
sortItemsBy | Sorts all the records by a selected field

These functions are available for every RecordSet object returned by the CF.query function to the Flash MX client. You invoke these functions as follows:

objectName.functionName();

For example, in the result function that you create to handle record set data returned by the CF.query function, you can reference the database column names returned in the record set using the getColumnNames RecordSet function:

function selectData_result ( result )
{
   //result holds the query data; employeesView is a Flash list box
   stringOutput.text = result.getColumnNames();
   _root.employeesView.setDataProvider(result);
}


Building a simple application

The following procedures describes how to build a simple server-side ActionScript application. The example application, a corporate personnel directory, uses the NetServices object to connect to the personneldirectory server-side ActionScript. The personneldirectory server-side ActionScript retrieves data from a ColdFusion data source and returns the results to the Flash movie as a RecordSet object.

Note: The server-side ActionScript that you create provides the backend services in an application.

This example requires the following:

  • A server-side ActionScript file named personneldirectory.asr that includes functions that interact with a ColdFusion data source.
  • A client-side Flash MX movie in which the NetServices object is created.

To create the application:

  1. Write the server-side ActionScript that performs the database query and returns data back to the client through the Flash Remoting service.
  2. Create the Flash movie interface.
  3. Define a search function that sends user data to the Flash service.
  4. Define a result function that captures the results returned from the Flash service.
  5. Ensure that the Flash movie has established a connection to the Flash Remoting service.

For more information, see the following sections:

  • Creating the Flash movie interface
  • Submitting user data to the Flash Remoting service
  • Capturing Flash Remoting service results
  • Checking for a Flash Remoting service connection


Write the server-side ActionScript

In this example, you create a search function that performs a simple search operation against a ColdFusion data source. This function accepts two arguments, firstName and lastName, and returns any records found that match these parameters.

Create a server-side ActionScript file that contains the following code, and save the file as personneldirectory.asr:

//search takes firstName lastName arguments
function search(firstName, lastName)
{
   searchdata = CF.query({datasource: "bigDSN",
      sql:"SELECT * from personnel WHERE fname = firstName AND lname = lastName"{);

   if (searchdata)
      return searchdata;
   else
      return null;
}


Creating the Flash movie interface

The Flash movie interface consists of one frame with a variety of text boxes and a submit button.

To create the Flash movie interface:

  1. In the Flash MX authoring environment, create a new Flash source file, and save it as pDirectory.fla.
  2. Create two input text boxes. Name one text box variable lastName and the other firstName.
  3. Create a dynamic text box, and name its variable status.
  4. Insert a list box component, and name it dataView.
  5. Insert a push button component.
  6. Save your work.

The following figure shows what the pDirectory Flash movie looks like:

This is a picture of the feature being described.


Submitting user data to the Flash Remoting service

To send data to a server-side ActionScript, you must create a function that passes the data from the Flash movie to the server-side ActionScript. The search function, applied at the frame level, collects the user-entered data from the firstName and lastName text boxes and passes the data as function arguments to the directoryService object, which is created when the Flash movie connects to the Flash Remoting service. For more information, see Checking for a Flash Remoting service connection.

The following is a Flash MX ActionScript example:

#include "NetServices.as"
function search()
{
   // The search() method is defined in the server-side AS file
   directoryService.search(firstName.text, lastName.text);
   dataView.setDataProvider(null);
   status.text = "waiting...";
}

In this example, the search function passes the contents of firstName and lastName text boxes to the server-side ActionScript.

The dataView.setDataProvider(null) function clears the dataView list box component. The status.text action displays a message in the status text box while the record set is being retrieved from the server-side ActionScript.


Capturing Flash Remoting service results

When you create a function that calls a server-side ActionScript function, you must also create a function to handle the data returned by the server-side ActionScript. You access data returned by a server-side ActionScript by defining a function with the same name as the function making the initial call, only you append _Result to the name.

For example, if you create a function called basicQuery to return query data, you also need to define a results function to handle returned data; the results function would be declared as basicQuery_result.

In the following example, the results function search_Result supplies the record set to the dataView.setDataProvider function:

function search_Result(resultset)
{
   dataView.setDataProvider(resultset);
   status.text = (0+resultset.getLength())+" names found.";
}

In this example, the _Result suffix tells the Flash Remoting service to return the results of the search function to this function. The dataView.setDataProvider(resultset) function assigns the results returned by the Flash Remoting service to the dataView list box. The status.text action displays the number of records returned by the Flash Remoting service.


Checking for a Flash Remoting service connection

To ensure that the Flash movie is connected to the Flash Remoting service, you use an if statement; for example:

if (inited == null)
{
   inited = true;
   NetServices.setDefaultGatewayUrl("http://localhost:8500/flashservices/
      gateway");
   gateway_conn = NetServices.createGatewayConnection();
   directoryService = gateway_conn.getService(personneldirectory, this);
   status.text = "Type into the text boxes, then click 'Search'";
}

In this example, inited is evaluated for a value. If it is null (not connected), the movie connects to the Flash Remoting service using the NetServices object. For more information about connecting to the Flash Remoting service, see Connecting to the Flash Remoting service.

Previous


Using the CF.http Function

This chapter describes how to use the CF.http ActionScript tag to conduct HTTP (HyperText Transfer Protocol) operations.

Contents
  • Overview
  • Data returned by the CF.http function
  • Using the CF.http Post method
  • Using the CF.http Get method
Next


Overview

The CF.http ActionScript function lets you to retrieve information from a remote HTTP server. HTTP Get and Post methods are supported.

  • Using the Get method, you send information to the remote server directly in the URL. This method is often used for a one-way transaction in which CF.http retrieves an object such as the contents of a web page.
  • The Post method can pass variables to a form or CGI program, and can also create HTTP cookies.


Using CF.http to retrieve HTML content

The most basic way to use the CF.http function is to use it with the Get method argument to retrieve a page from a specified URL. For the CF.http function, the Get method is the default.

For example, the following server-side code retrieves file content from the specified URL:

function basicGet(url)
{
   // Invoke with just the url argument. This is an HTTP Get.
   result = CF.http(url);
   return result.get("Filecontent");
}

On the client side, your code could look like the following:

#include "NetServices.as"
NetServices.setDefaultGatewayUrl("http://mycfserver:8500");
gatewayConnnection = NetServices.createGatewayConnection();
myHttp = gatewayConnnection.getService("httpFuncs", this);

// This is the server-side function invocation
url = "http://anyserver.com";
myHttp.basicGet(url);

// Create the results function
function basicGet_result()
{
   url = "http://anyserver.com
   ssasFile.basicGet(url)
}


Data returned by the CF.http function

The CF.http function returns an object that contains properties, also known as attributes, that you reference to access the contents of the file returned, header information, HTTP status codes, and so on. The following table shows the available properties:

Property
Description
Text
A Boolean value indicating whether the specfied URL location contains text data.
Charset
The charset used by the document specified in the URL.
HTTP servers normally provide this information, or the charset is specified in the charset parameter of the Content-Type header field of the HTTP protocol. For example, the following HTTP header announces that the character encoding is EUC-JP:
Content-Type: text/html; charset=EUC-JP
Header
Raw response header. For example, macromedia.com returns the following header :
HTTP/1.1 200 OK
Date: Mon, 04 Mar 2002 17:27:44 GMT
Server: Apache/1.3.22 (Unix) mod_perl/1.26
Set-Cookie: MM_cookie=207.22.48.162.4731015262864476;
path=/; expires=Wed, 03-Mar-04 17:27:44 GMT;
domain=.macromedia.com
Connection: close
Content-Type: text/html
Filecontent
File contents, for text and MIME files.
Mimetype
MIME type. Examples of content types include "text/html", "image/png", "image/gif", "video/mpeg", "text/css", and "audio/basic".
Responseheader
Response header. If there is one instance of a header key, this value can be accessed as a simple type. If there is more than one instance, values are put in an array in the responseHeader structure.
Statuscode
HTTP error code and associated error string. Common HTTP status codes returned in the response header include the following:
400: Bad Request
401: Unauthorized
403: Forbidden
404: Not Found
405: Method Not Allowed


Referencing HTTP Post parameters CF.http

In order to pass HTTP Post parameters in the CF.http function, you must construct an array of objects and assign this array to a variable named params. The following arguments can only be passed as an array of objects in the params argument of the CF.http function.

Parameter
Description
name
The variable name for data that is passed
type
Transaction type:
  • URL
  • FormField
  • Cookie
  • CGI
  • File
value
Value of URL, FormField, Cookie, File, or CGI variables that are passed

In the following example, the CF.http function passes HTTP Post parameters in an array of objects.

function postWithParamsAndUser()
{
   // Setup the array of post parameters. These are just like cfhttpparam tags.
   params = new Array();
   params[1] = {name:"arg2", type:"URL", value:"value2"};

   url = "http://localhost:8500/";

   // Invoke with the method, url, params, username, and password
   result = CF.http("post", url, params, "karl", "salsa");
   return result.get("Filecontent");
}


Using the CF.http Post method

Use the Post method to send cookie, form field, CGI, URL, and file variables to a specified ColdFusion page or CGI program for processing. For POST operations, you must use the params argument for each variable that you post. The Post method passes data to a specified ColdFusion page or an executable that interprets the variables being sent and returns data.

For example, when you build an HTML form using the Post method, you specify the name of the page to which form data is passed. You use the Post method in CF.http in a similar way. However, with CF.http, the page that receives the Post does not display anything.

function postWithParams()
{
   // Setup the array of post parameters. These are just like cfhttpparam tags.
   // This example passes formfield data to a specified URL.
   params = new Array();
   params[1] = {name:"Formfield1", type:"FormField", value:"George"};
   params[2] = [name:"Formfield2", type:"FormField", value:"Brown"};

   url = "http://localhost:8500/";

   // Invoke CF.http with the method, url, and params
   result = CF.http("post", url, params);
   return result.get("Filecontent");
}


Using the CF.http Get method

You use the Get method to retrieve files, including text and binary files, from a specified server. You reference properties of the object returned by the CF.http function to access things like file content, header information, MIME type, and so on.

For more information about CF.http function properties, see ColdFusion ActionScript Functions.


Example using the Get method

The following example of using the CF.http function shows a common approach to retrieving data from the web.

// Returns content of URL defined in url variable
// This example uses positional argument style
function get()
{
   url - "http://www.macromedia.com/software/coldfusion/";

   //Invoke with just the url argument. Get is the default.
   result = CF.http(url);
   return result.get("Filecontent");
}
Previous


ColdFusion ActionScript Functions

This chapter explains the syntax and usage of the two currently supported server-side ActionScript funtions, CF.query and CF.http.

Contents
  • CF.query
  • CF.htttp
Next


CF.query

Description

Performs queries against ColdFusion data sources.

Return value

Returns a RecordSet object. For information about methods that you can use to manipulate the record set returned by the CF.query function, see Methods available in the RecordSet ActionScript class.

Syntax

CF.query
   ({
      datasource:"data source name",
      sql:"SQL stmts",
      username:"username",
      password:"password",
      maxrows:number,
      timeout:milliseconds
   })

Arguments

Arguments | Req/Opt | Description
datasource | Required | Name of the data source from which query retrieves data.
sql | Required | SQL statement.
username | Optional | Overrides the username specified in the data source setup.
password | Optional | Overrides the password specified in the data source setup.
maxrows | Optional | Maximum number of rows to return in the record set.
timeout | Optional | Maximum number of seconds for the query to execute before returning an error indicating that query has timed out. Can only be used in named arguments.

Usage

You can code the CF.query function using named arguments or using positional arguments. You can invoke all supported arguments using the named argument style, as follows:

CF.query({datasource:"datasource", sql:"sql stmt",
   username:"username", password:"password", maxrows:"maxrows",
   timeout:"timeout"});

Note: The named argument style uses curly braces {} to surround the function arguments.

Positional arguments let you use a shorthand coding style. However, not all arguments are supported for the positional argument style. Use the following schemas to code the CF.query function using positional arguments:

CF.query(datasource, sql);
CF.query(datasource, sql, maxrows);
CF.query(datasource, sql, username, password);
CF.query(datasource, sql, username, password, maxrows);

Note: When using positional arguments, do not use curly braces {}.

Example

// Define a function to do a basic query
// Note use of positional arguments
function basicQuery()
{
   result = CF.query("myquery", "cust_data", "SELECT * from tblParks");
   return result;
}

// Example function declaration using named arguments
function basicQuery()
{
   result = CF.query({datasource:"cust_data", sql:"SELECT * from tblParks"});
   return result;
}

// Example of query function using maxrows argument
function basicQueryWithMaxRows()
{
   result = CF.query("cust_data", "SELECT * from tblParks", 25);
   return result;
}

// Example of CF.query with username and password
function basicQueryWithUser()
{
   result = CF.query("cust_data", "SELECT * from tblParks",
      "wsburroughs", "migraine1");
   return result;
}


Methods available in the RecordSet ActionScript class

The record set returned by the CF.query function can be manipulated using methods in the RecordSet ActionScript class. The following are some of the methods available in the RecordSet class:

  • RecordSet.getColumnnames
  • RecordSet.getLength
  • RecordSet.getItemAt
  • RecordSet.getItemID
  • RecordSet.sortItemsBy
  • RecordSet.getNumberAvailable
  • RecordSet.filter
  • RecordSet.sort

For more detailed information about the RecordSet ActionScript class, see Using Flash Remoting.


CF.htttp

Description

Executes HTTP POST and GET operations on files. POST operations upload MIME file types to a server, or post cookie, formfield, URL, file, or CGI variables directly to a server.

Return value

Returns an object containing properties that you reference to access data. For available properties returned by the CF.http function, see Properties available with the CF.http object.

Syntax

CF.http
   ({
      method:"get or post",
      url:"URL",
      username:"username",
      password:"password",
      resolveurl:"yes or no",
      params:arrayvar,
      path:"path",
      file:"filename"
   })

Arguments

Arguments
Req/Opt
Description
method
Required
Two arguments are supported:
  • get: downloads a text or binary file or creates a query from the contents of a text file.
  • post: sends information to the server page or CGI program for processing. Requires the params argument.
url
Required
The absolute URL of the host name or IP address of server on which the file resides. The URL must include the protocol (http or https) and host name.
username
Optional
When required by a server, a username.
password
Optional
When required by a server, a password.
resolveurl
Optional
For Get and Post methods.
  • Yes or No. Default is No.
For GET and POST operations, if Yes, page reference that is returned into the Filecontent property has its internal URLs fully resolved, including port number, so that links remain intact. The following HTML tags, which can contain links, are resolved:
- img src
- a href
- form action
- applet code
- script src
- embed src
- embed pluginspace
- body background
- frame src
- bgsound src
- object data
- object classid
- object codebase
- object usemap
params
Optional
HTTP parameters passed as an array of objects. Supports the following parameter types:
  • name
  • type
  • value
CF.http params are passed as an array of objects. The params argument is required for POST operations.
For detailed information about each params argument, see CF.http parameters .
path
Optional
The path to the directory in which to store files. When using the path argument, the file argument is required.
file
Optional
Name of the file that is accessed. For GET operations, defaults to name specified in the url argument. Enter path information in the path attribute.

Usage

You can code the CF.http function using named arguments or positional arguments. You can invoke all supported arguments using the named argument style, as follows:

CF.http({method:"method", url:"URL", username:"username", password:"password",
   resolveurl:"yes or no", params:arrayvar,
   path:"path", file:"filename"});

Note: The named argument style uses curly braces {} to surround the function arguments.

Positional arguments let you use a shorthand coding style. However, not all arguments are supported for the positional argument style. Use the following schemas to code the CF.http function using positional arguments:

CF.http(url);
CF.http(method, url);
CF.http(method, url, username, password);
CF.http(method, url, params, username, password);

Note: When using positional arguments, do not use curly braces {}.


CF.http parameters

The following parameters can only be passed as an array of objects in the params argument in the CF.http function:

Parameter
Description
name
The variable name for data that is passed
type
The transaction type:
  • URL
  • FormField
  • Cookie
  • CGI
  • File
value
Value of URL, FormField, Cookie, File, or CGI variables that are passed


Properties available with the CF.http object

The CF.http function returns data as a set of object properties:

Property
Description
Text
A Boolean value that indicates whether the specfied URL location contains text data.
Charset
The charset used by the document specified in the URL.
HTTP servers normally provide this information, or the charset is specified in the charset parameter of the Content-Type header field of the HTTP protocol. For example, the following HTTP header announces that the character encoding is EUC-JP:
Content-Type: text/html; charset=EUC-JP
Header
Raw response header. For example, macromedia.com returns the following header:
HTTP/1.1 200 OK
Date: Mon, 04 Mar 2002 17:27:44 GMT
Server: Apache/1.3.22 (Unix) mod_perl/1.26
Set-Cookie: MM_cookie=207.22.48.162.4731015262864476;
path=/; expires=Wed, 03-Mar-04 17:27:44 GMT;
domain=.macromedia.com
Connection: close
Content-Type: text/html
Filecontent
File contents, for text and MIME files.
Mimetype
MIME type. Examples of content types include text/html, image/png, image/gif,"video/mpeg, text/css, and audio/basic.
Responseheader
Response header. If there is one instance of a header key, value can be accessed as simple type. If there is more than one instance, values are put in an array in responseHeader structure.
Statuscode
HTTP error code and associated error string. Common HTTP status codes returned in the response header include:
400: Bad Request
401: Unauthorized
403: Forbidden
404: Not Found
405: Method Not Allowed

You access these attributes using the get function:

function basicGet()
{
    url = "http://localhost:8500/";

    // Invoke with just the url. This is an http get.
    result = CF.http(url);
    return result.get("Filecontent");
}

Example

The following examples show a number of the ways to use the CF.http function:

function postWithNamedArgs()
{
   // Set up the array of post parameters.
   params = new Array();
   params[1] = {name:"arg1", type:"FormField", value:"value1"};
   params[2] = {name:"arg2", type:"URL", value:"value2"};
   params[3] = {name:"arg3", type:"CGI", value:"value3"};

   url = "http://localhost:8500/";

   path = application.getContext("/").getRealPath("/");
   file = "foo.txt";

   result = CF.http({method:"post", url:url, username:"karl", password:"salsa",
resolveurl:true, params:params, path:path, file:file});

   if (result)
      return result.get("Statuscode");
   return null;
}

// Example of a basic HTTP get operation
// Shows that HTTP Get is the default
function basicGet()
{
   url = "http://localhost:8500/";

   // Invoke with just the URL. This is an HTTP Get.
   result = CF.http(url);
   return result.get("Filecontent");
}

// Example showing simple array created to pass params arguments
function postWithParams()
{
   // Set up the array of post parameters. These are just like cfhttpparam tags.
   params = new Array();
   params[1] = {name:"arg2", type:"URL", value:"value2"};

   url = "http://localhost:8500/";

   // Invoke with the method, url, and params
   result = CF.http("post", url, params);
   return result.get("Filecontent");
}

// Example with username and params arguments
function postWithParamsAndUser()
{
   // Set up the array of post parameters. These are just like cfhttpparam tags.
   params = new Array();
   params[1] = {name:"arg2", type:"URL", value:"value2"};

   url = "http://localhost:8500/";

   // Invoke with the method, url, params, username, and password
   result = CF.http("post", url, params, "karl", "salsa");
   return result.get("Filecontent");
}

Previous


Trademarks

Afterburner, AppletAce, Attain, Attain Enterprise Learning System, Attain Essentials, Attain Objects for Dreamweaver, Authorware, Authorware Attain, Authorware Interactive Studio, Authorware Star, Authorware Synergy, Backstage, Backstage Designer, Backstage Desktop Studio, Backstage Enterprise Studio, Backstage Internet Studio, ColdFusion, Design in Motion, Director, Director Multimedia Studio, Doc Around the Clock, Dreamweaver, Dreamweaver Attain, Drumbeat, Drumbeat 2000, Extreme 3D, Fireworks, Flash, Fontographer, FreeHand, FreeHand Graphics Studio, Generator, Generator Developer's Studio, Generator Dynamic Graphics Server, JRun, Knowledge Objects, Knowledge Stream, Knowledge Track, Lingo, Live Effects, Macromedia, Macromedia M Logo & Design, Macromedia Flash, Macromedia Xres, Macromind, Macromind Action, MAGIC, Mediamaker, Object Authoring, Power Applets, Priority Access, Roundtrip HTML, Scriptlets, SoundEdit, ShockRave, Shockmachine, Shockwave, Shockwave Remote, Shockwave Internet Studio, Showcase, Tools to Power Your Ideas, Universal Media, Virtuoso, Web Design 101, Whirlwind and Xtra are trademarks of Macromedia, Inc. and may be registered in the United States or in other jurisdictions including internationally. Other product names, logos, designs, titles, words or phrases mentioned within this publication may be trademarks, servicemarks, or tradenames of Macromedia, Inc. or other entities and may be registered in certain jurisdictions including internationally.

This guide contains links to third-party websites that are not under the control of Macromedia, and Macromedia is not responsible for the content on any linked site. If you access a third-party website mentioned in this guide, then you do so at your own risk. Macromedia provides these links only as a convenience, and the inclusion of the link does not imply that Macromedia endorses or accepts any responsibility for the content on those third-party sites.

Next


Apple Disclaimer

APPLE COMPUTER, INC. MAKES NO WARRANTIES, EITHER EXPRESS OR IMPLIED, REGARDING THE ENCLOSED COMPUTER SOFTWARE PACKAGE, ITS MERCHANTABILITY OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. THE EXCLUSION OF IMPLIED WARRANTIES IS NOT PERMITTED BY SOME STATES. THE ABOVE EXCLUSION MAY NOT APPLY TO YOU. THIS WARRANTY PROVIDES YOU WITH SPECIFIC LEGAL RIGHTS. THERE MAY BE OTHER RIGHTS THAT YOU MAY HAVE WHICH VARY FROM STATE TO STATE.

Copyright © 2001 Macromedia, Inc. All rights reserved. This manual may not be copied, photocopied, reproduced, translated, or converted to any electronic or machine-readable form in whole or in part without prior written approval of Macromedia, Inc.

Part number: ZCF60M700


Acknowledgments

Project Management: Stephen M. Gilson

Writing: All of the Macromedia Newton writing team

Editing: All of the Macromedia Newton editing team

First Edition: April 2002

Macromedia, Inc.
600 Townsend St.
San Francisco, CA 94103

Help Version: 6.0.5

Previous


Preparing to Build the Sample Application

In this tutorial, you will build a simple ColdFusion web application for a fictitious travel company called Compass Travel. Compass Travel markets a wide range of adventure trips to the public through its website. Trip coordinators at Compass Travel are responsible for maintaining the trip information made available to the public. You will build the sample tutorial application to assist the trip coordinators in maintaining trip information in the Compass Travel database.

ColdFusion development is the emphasis of the tutorial, therefore, you will not need to design or build the Compass Travel database. It is important, however, for you to be familiar with the layout of the database. Additionally, you must understand the functional requirements that will help in determining the application design. This lesson provides an overview of these application design steps, while the remainder of this book guides you through the lessons on constructing the sample application.

Next


000_titl.htm

ColdFusion MX Documentation

Copyright © 1995-2002 Macromedia, Inc.
All rights reserved.
Trademarks and Acknowlegments